问题
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?
回答1:
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/
回答2:
Try to override constructor like this:
class SomeData(
@SerializedName("user_name") val name: String,
@SerializedName("user_city") val city: String,
var notNullableValue: String = "") {
constructor() : this("","","")
}
Now after server response you can check the notNullableValue is not null - its empty
来源:https://stackoverflow.com/questions/45793451/kotlin-not-nullable-value-can-be-null