12

我有后端返回我一些 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 中可以为空吗?

4

2 回答 2

17

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

从构造函数中删除="",你会得到一个错误。

编辑:发现问题。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/

于 2017-08-21T09:30:49.183 回答
4

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

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

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

于 2017-11-24T15:40:14.947 回答