I have backend that return me some json.

我将其解析为我的类:

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

Use gson converter factory:

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

And in my interface:

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

然后,我从服务器检索数据(使用rxJava),没有任何错误.但我预计会出现错误,因为我认为我应该这样做(以防止gson转换器错误,因为我的JSON响应中没有出现notNullableValue):

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

在从后端接收数据并使用构造函数将数据解析到我的SomeData类(没有def值)之后,notNullableValue == null的值.

据我所知,在kotlin中,不可为空的值可以为空吗?

推荐答案

是的,这是因为你给了它一个默认值.当然,它永远不会为空.这就是默认值的全部意义.

Remove ="" from constructor and you will get an error.

Edit: Found the issue. GSON uses the magic sun.misc.Unsafe class which has an allocateInstance method which is obviously considered very unsafe because what it does is skip initialization (constructors/field initializers and the like) and security checks. So there is your answer why a Kotlin non-nullable field can be null. Offending code is in com/google/gson/internal/ConstructorConstructor.java:223

Some interesting details about the Unsafe class: http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/

Kotlin相关问答推荐

创建具有共同父类型的两种不同类型对象的列表的最有效方法是什么?

在Kotlin 有更好的结合方式?

如何在Docker中使用Selenium和chromedriver?

如何从 Period.between() 返回的字符串中提取信息? (Kotlin )

Rabin-Karp字符串匹配的实现(Rolling hash)

测试协程和线程之间的差异,我在kotlin中使用线程时无法得到OOM错误

Kotlin 插件之间的区别

is return inside function definition 也是 kotlin 中的表达式

在 Kotlin 中,当枚举类实现接口时,如何解决继承的声明冲突?

使用 Hilt 注入 CoroutineWorker

Kotlin:泛型、反射以及类型 T 和 T:Any 之间的区别

Map.mapTo 到另一个map

带有迭代器函数的 Kotlin 无限序列

将 Android Studio 升级到 3.1.0 后的 Android Support 插件错误

Kotlin get字段注释始终为空

如果 Maybe 完成,则从其他来源将 Maybe 转换为 Single

Mocked suspend函数在Mockito中返回null

具有泛型param的Kotlin抽象类和使用类型param的方法

Kotlin 中内部可见性修饰符的范围

使用 java lambda 调用 kotlin 函数时,Kotlin 无法访问 kotlin.jvm.functions.Function1