Anas Alaa
Anas Alaa

Reputation: 73

Notnull variable become nullable after transpiling kotlin to java

when I have a kotlin class like that one suppose that uniqueName is NotNull.

data class Payload(
        @SerializedName("unique_name") val uniqueName: String, 
        @SerializedName("nbf") val nbf: Int, 
        @SerializedName("exp") val exp: Int, 
        @SerializedName("iat") val iat: Int
)

but when i tested this code

    @Test
    fun fromStringJsonToObject4() {
        val gsonHelper = GsonHelper()
        val payloadJsonString = "{}"
        val payload = Payload("", 0, 0, 0)

        assertEquals(gsonHelper.fromStringJsonToObject(payloadJsonString, Payload::class.java), payload)
    }

it returns

Expected :Payload(uniqueName=null, nbf=0, exp=0, iat=0)
Actual   :Payload(uniqueName=, nbf=0, exp=0, iat=0)

so how uniqueName in my object become nullable ??

Upvotes: 2

Views: 154

Answers (2)

Marko Topolnik
Marko Topolnik

Reputation: 200206

This line

gsonHelper.fromStringJsonToObject(payloadJsonString, Payload::class.java)

delegates to the low-level, unspecified Unsafe.allocateInstance() call, which allocates an object without calling any constructors. It then uses reflection to write the fields. This circumvents the barrier where Kotlin is supposed to establish its static typing invariants: the assertions in the constructor code.

This is why the object creation will succeed and invalidate Kotlin's static proofs about the object. A non-null property will end up with a null value.

You should avoid using not-nullable properties for objects created through reflection by Java libraries that are not aware of Kotlin's nullability rules. This will let the Kotlin side start from a valid point and then the compiler will guide you through the usual ceremony of lifting nullable to not-nullable values as required.

Upvotes: 4

nhaarman
nhaarman

Reputation: 100438

It's not nullable: if you try to access the uniqueName field you will get a NPE.

Gson does not know about nullable/nonnullable properties, and will use default values for missing entries. Your json does not contain unique_name, and the default value for String is null.

Upvotes: 0

Related Questions