首页 文章

Kotlin不可空的值可以为null吗?

提问于
浏览
10

我有后端给我一些json .

我把它解析给我的 class :

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 = "")

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

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

2 回答

  • 15

    是的,那是因为你给它一个默认值 . 当然,它永远不会是空的 . 这是默认值的重点 .

    从构造函数中删除 ="" ,您将收到错误 .

    编辑:发现问题 . GSON使用了具有 allocateInstance 方法的魔法 sun.misc.Unsafe 类,该方法显然被认为是 unsafe ,因为它的作用是跳过初始化(构造函数/字段初始化器等)和安全检查 . 所以你的答案是为什么Kotlin非可空字段可以为空 . 违规代码在 com/google/gson/internal/ConstructorConstructor.java:223

    关于 Unsafe 类的一些有趣细节:http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/

  • 2

    尝试覆盖这样的构造函数:

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

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

相关问题