Search code examples
gsonkotlinkotlin-null-safety

Kotlin not nullable value can be null?


I have backend that return me some json.

I parse it to my class:

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();
}

Then I retrieve data from the server (with rxJava) without any error. But I expected an error because I thought I should do something like this (to prevent GSON converter error, because notNullableValue is not present in my JSON response):

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

After the data is received from backend and parsed to my SomeData class with constructor without def value, the value of the notNullableValue == null.

As I understand not nullable value can be null in Kotlin?


Solution

  • Yes, that is because you're giving it a default value. Ofcourse it will never be null. That's the whole point of a default value.

    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/