gson Kotlin不可为空值是否可以为空?

t1qtbnec  于 2022-11-06  发布在  Kotlin
关注(0)|答案(2)|浏览(197)

我有后端返回我一些json。
我把它解析到我的类中:

class SomeData(
  @SerializedName("user_name") val name: String,
  @SerializedName("user_city") val city: String,
  var notNullableValue: String
)

使用gson转换器工厂:

Retrofit retrofit = new Retrofit.Builder()
  .baseUrl(ENDPOINT)
  .client(okHttpClient)
  .addConverterFactory(GsonConverterFactory.create(gson))
  .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
  .build();

而在我接口道:

interface MyAPI {
    @GET("get_data")
    Observable<List<SomeData>> getSomeData();
}

然后我从服务器检索数据(使用rxJava),没有任何错误。但是我预料到了错误,因为我认为我应该这样做(为了防止GSON转换器错误,因为notNullableValue没有出现在我的JSON响应中):

class SomeData @JvmOverloads constructor(
  @SerializedName("user_name") val name: String,
  @SerializedName("user_city") val city: String,
  var notNullableValue: String = ""
)

从后端接收到数据并解析到我的SomeData类后,使用构造函数不带def值,notNullableValue == null的值。
据我所知,在Kotlin中不可为空的值可以为空?

wbgh16ku

wbgh16ku1#

是的,那是因为你给了它一个默认值。当然它永远不会是空的。这就是默认值的全部意义。
从构造函数中移除="",您将得到一个错误。
编辑:发现了这个问题。GSON使用了一个神奇的sun.misc.Unsafe类,它有一个allocateInstance方法,很明显,这个方法被认为非常unsafe,因为它所做的是跳过初始化(构造函数/字段初始化器等)和安全检查。所以,这就是为什么Kotlin不可空字段可以为空的答案。有问题的代码在com/google/gson/internal/ConstructorConstructor.java:223
关于Unsafe类的一些有趣的细节:http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/

68bkxrlz

68bkxrlz2#

尝试如下重写构造函数:

class SomeData(
        @SerializedName("user_name") val name: String,
        @SerializedName("user_city") val city: String,
        var notNullableValue: String = "") {
    constructor() : this("","","")
}

现在,在服务器响应后,您可以检查notNullableValue是否为空-其为空

相关问题