在Kotlin你可以创建一个 data class
:
data class CountriesResponse(
val count: Int,
val countries: List<Country>,
val error: String)
然后你可以用它来解析JSON,例如"{n: 10}" . 在这种情况下,您将拥有一个从 Retrofit
, Fuel
或 Gson
收到的对象 val countries: CountriesResponse
,其中包含以下值: count = 0, countries = null, error = null
.
在Kotlin + Gson - How to get an emptyList when null for data class中,您可以看到另一个示例 .
当您稍后尝试使用 countries
时,您将在此处获得异常: val size = countries.countries.size
:"kotlin.TypeCastException: null cannot be cast to non-null type kotlin.Int" . 如果您编写代码并在访问这些字段时使用 ?
,Android Studio将突出显示 ?.
并警告: Unnecessary safe call on a non-null receiver of type List<Country>
.
那么,我们应该在数据类中使用 ?
吗?为什么应用程序在运行时可以将 null
设置为不可为空的变量?
1 回答
发生这种情况是因为Gson使用不安全(如
java.misc.Unsafe
)实例构造机制来创建类的实例,绕过它们的构造函数,然后直接设置它们的字段 .有关一些研究,请参阅此问答:Gson Deserialization with Kotlin, Initializer block not called .
因此,Gson忽略了构造逻辑和类状态不变量,因此不建议将它用于可能受此影响的复杂类 . 它也忽略了setter中的值检查 .
考虑一个Kotlin感知的序列化解决方案,例如Jackson(在上面链接的Q&A中提到)或kotlinx.serialization .