fastjson 反序列化时对kotlin 字段默认值的处理

问题描述

使用fastjson对json字符串反序列化时,数据类中设置的默认值不生效。例如json字符串:

{
        "answerBoardUid": "104ba939791d4a05952f49d2cf5e382e",
        "answerStudentNumber": 5,
        "correct": 0,
        "correctNumber": 1,
        "correctOptions": [
            "A"
        ],
        "correctRate": 20,
        "questionNumber": 1,
        "slideHash": "8c24470d4148e42fd850caf589da1696",
        "totalStudentNumber": 6
    }

数据类如下:

    data class QuestionDetailInfo(
        var answerBoardUid:String,//答题板id
        var type:AnswerBoardType=AnswerBoardType.OBJECTIVE, //答题板类型
        var correctOptions:List<String> = emptyList(),//正确选项
        var options:List<String>?=null,//所选选项
        var correct:Int=0,//是否回答正确 0:没答  1:正确  2:错误
        var questionNumber:Int=0,//题号
        var correctRate:Int=0,
        var correctNumber:Int=0,
        var totalStudentNumber:Int=0,
        var answerStudentNumber:Int=0,
        var slideHash:String?=null) 

反序列化后对象,type字段值为null。

如果数据类改为如下:

    data class QuestionDetailInfo(
        var answerBoardUid:String="",//答题板id
        var type:AnswerBoardType=AnswerBoardType.OBJECTIVE, //答题板类型
        var correctOptions:List<String> = emptyList(),//正确选项
        var options:List<String>?=null,//所选选项
        var correct:Int=0,//是否回答正确 0:没答  1:正确  2:错误
        var questionNumber:Int=0,//题号
        var correctRate:Int=0,
        var correctNumber:Int=0,
        var totalStudentNumber:Int=0,
        var answerStudentNumber:Int=0,
        var slideHash:String?=null) 

则type值为AnswerBoardType.OBJECTIVE

本文将探索这种差异的原因

fastjson 如何进行反序列化

反序列化过程

jsonString ——> FastjsonASMDeserializer_x_xxx.class ——> JavaBean

FastjsonASMDeserializer_x_xxx.class 为fastjson生成的字节码

如何去探究其反序列化过程

    data class QuestionDetailInfo(
        var answerBoardUid:String,//答题板id
        var type:AnswerBoardType=AnswerBoardType.OBJECTIVE, //答题板类型
        var correctOptions:List<String> = emptyList(),//正确选项
        var options:List<String>?=null,//所选选项
        var correct:Int=0,//是否回答正确 0:没答  1:正确  2:错误
        var questionNumber:Int=0,//题号
        var correctRate:Int=0,
        var correctNumber:Int=0,
        var totalStudentNumber:Int=0,
        var answerStudentNumber:Int=0,
        var slideHash:String?=null) 

    data class SeewoWxUserBindTopicDTO(
        var userId: String = "",
        var openId: String = "",
        var extendParam: String = "")
    public com.seewo.classroom.core.dto.weixin.SeewoWxUserBindTopicDTO();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=6, locals=1, args_size=1
         0: aload_0
         1: aconst_null
         2: aconst_null
         3: aconst_null
         4: bipush        7
         6: aconst_null
         7: invokespecial #48                 // Method "<init>":(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
        10: return


    public com.seewo.classroom.core.entity.course.QuestionDetailInfo();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #84                 // Method java/lang/Object."<init>":()V
         4: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lkotlin/Unit;

发现这两个类的 默认构造函数实现不一样 这最终导致了反序列化时,对默认值的处理不同