问题描述
我把它解析到我的课上: class SomeData(
@SerializedName(user_name)val name:String,
@SerializedName(user_city)val city:String,
var notNullableValue:字符串)
使用gson转换工厂:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ENDPOINT)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson) )
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
并在我的界面中:
接口MyAPI {
@GET(get_data)
可观察< List< SomeData>> getSomeData();
}
然后我从服务器(使用rxJava)检索数据,没有任何错误。但是我期望出现一个错误,因为我认为我应该这样做(为了防止GSON转换器错误,因为在我的JSON响应中不存在 notNullableValue
):
class SomeData @JvmOverloads构造函数(
@SerializedName(user_name)val名称:String,
@SerializedName(user_city )val city:String,
var notNullableValue:String =)
数据是从后端接收的,并且使用没有def值的构造函数解析到我的SomeData类, notNullableValue == null 的值。
据我了解,在Kotlin中不可为空的值可以为null?
从构造函数中移除 =
,您将会看到一个错误。
编辑:找到问题。 GSON使用具有 allocateInstance
方法的魔术 sun.misc.Unsafe
类,该方法显然被认为是<$ c $不安全因为它做的是跳过初始化(构造函数/字段初始值设定项等)和安全检查。所以你的答案为什么一个Kotlin不可为空的字段可以为空。有效代码位于 com / google / gson / internal / ConstructorConstructor.java:223
不安全
class:
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?
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/
这篇关于Kotlin不可为空值可以为null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!