web-dev-qa-db-ja.com

Kotlinのnull許容値ではない値をnullにすることができますか?

私は私にいくつかの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 = "")

データがバックエンドから受信され、def値のないコンストラクターを使用してSomeDataクラスに解析された後、notNullableValue == nullの値。

Kotlinではnull許容値がnullになる可能性があることを理解していますか?

12
bitvale

はい、それはあなたがそれにデフォルト値を与えているからです。もちろん、それがnullになることはありません。これがデフォルト値の要点です。

削除する =""コンストラクターから、エラーが発生します。

編集:問題が見つかりました。 GSONは魔法を使用しますSun.misc.UnsafeallocateInstanceメソッドを持つクラス。これは明らかに非常にunsafeと見なされます。これは、初期化(コンストラクター/フィールド初期化子など)とセキュリティチェックをスキップするためです。したがって、Kotlinのnull許容不可能なフィールドがnullになる理由があります。問題のあるコードはcom/google/gson/internal/ConstructorConstructor.Java:223

Unsafeクラスに関するいくつかの興味深い詳細: http://mishadoff.com/blog/Java-magic-part-4-Sun-dot-misc-dot-unsafe/

17
Strelok

次のようにコンストラクターをオーバーライドしてみてください。

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

サーバーの応答後、notNullableValueがnullではないことを確認できます-空です

3
Yuriy