关于kotlin gson序列化时出现null的一些注意点

现在前后端基本都用json来传输数据,kotlin因为有空校验比如这个类:


data class XXXDataBean(
        var code:Int = 0,
        var data: DataBean = DataBean()) {
    class DataBean {
    }
}

在kotlin中定义的都是非空,可是如果给的json是这样:

{
    "code":1,
    "data":null
}

Gson().fromJson(json,XXXDataBean::class.java)拿到的对象中,data会为空。如果json不给data的话,那么data依然是初始化时的那个DataBean()


5.1 更新
发现一个新的问题

数据类:

data class User(
    var age :Int,
    var name :String= "lucy"
)

在AndroidStudio中点击Tools-Kotlin-Show Kotlin Bytecode会出现字节码,再点击Decompile能看到反编译的java文件

image

上面那个User的构造中,可以看到age没有默认值,name给了个默认值,此时,java中的构造为

public User(int age, @NotNull String name) {
      Intrinsics.checkParameterIsNotNull(name, "name");
      super();
      this.age = age;
      this.name = name;
   }

   // $FF: synthetic method
   public User(int var1, String var2, int var3, DefaultConstructorMarker var4) {
      if ((var3 & 2) != 0) {
         var2 = "lucy";
      }
      this(var1, var2);
   }

如果User中的参数都给一个默认值,如

data class User(
    var age :Int=13,
    var name :String= "lucy"
)

则对应java的构造会变成3个,多了个无参构造。

public User(int age, @NotNull String name) {
      Intrinsics.checkParameterIsNotNull(name, "name");
      super();
      this.age = age;
      this.name = name;
   }

   // $FF: synthetic method
   public User(int var1, String var2, int var3, DefaultConstructorMarker var4) {
      if ((var3 & 1) != 0) {
         var1 = 13;
      }

      if ((var3 & 2) != 0) {
         var2 = "lucy";
      }

      this(var1, var2);
   }

   public User() {
      this(0, (String)null, 3, (DefaultConstructorMarker)null);
   }

那么问题来了:
在构造都有默认值的情况下,Gson是能够正常解析的。但如果有非默认值的时候,也就是java文件中没有空参构造时,

        val json =""
        val user2 = Gson().fromJson(json, User::class.java)
        println("gson: $user2")

结果为:gson: User(age=0, name=null),即使我们给了name一个初始值,即使我们标明了name@NotNull,解析的结果依然是个null。

结论:Gson解析需要一个空参构造,而kotlin如果构造中每个参数都有默认值的时候,会有一个空参,并且会正确的将默认值赋值。所以Gson可以正常解析。如果kotlin的构造有参数没有默认值,就会出问题。

你可能感兴趣的:(关于kotlin gson序列化时出现null的一些注意点)