当前位置: 首页 > 知识库问答 >
问题:

为什么Kotlin数据类可以在GSON的不可为空字段中有为空?

邢永安
2023-03-14

在Kotlin中,您可以创建数据类:

data class CountriesResponse(
    val count: Int,
    val countries: List<Country>,
    val error: String)

然后可以使用它解析JSON,例如“{n:10}”。在这种情况下,您将有一个对象val Country:CountriesResponse,从RevovitFuelGSON接收,它包含以下值:Count=0,Countrys=null,error=null

在Kotlin+GSON-How to get a emptyList when null for data类中,您可以看到另一个示例。

当您以后尝试使用countries时,您将在这里得到一个异常:val size=countries.countries.size:“Kotlin.TypeCastException:null不能被强制转换为非null类型Kotlin.int”。如果您编写代码并在访问这些字段时使用,Android Studio将突出显示?.并警告:对List 类型的非空接收器进行不必要的安全调用。

那么,我们是否应该在数据类中使用?为什么应用程序可以在运行时将null设置为不可为空的变量?

共有1个答案

洪鸿博
2023-03-14

发生这种情况是因为Gson使用了一种不安全的(如java.misc.unsafe)实例构造机制来创建类的实例,绕过它们的构造函数,然后直接设置它们的字段。

有关一些研究,请参阅此问答:使用Kotlin的Gson反序列化,未调用初始化器块。

因此,Gson忽略了构造逻辑和类状态不变量,因此不建议将其用于可能受此影响的复杂类。它也会忽略setter中的值检查。

考虑一个Kotlin感知的序列化解决方案,例如Jackson(在上面链接的问答中提到)或kotlinx.serialization

 类似资料:
  • 我有返回给我一些JSON后端。 我将其解析为我的类: 然后我从服务器(使用rxJava)检索数据,没有任何错误。但是我预料到了一个错误,因为我认为我应该做这样的事情(以防止GSON转换器错误,因为在我的JSON响应中不存在): 在从后端接收数据并将其解析到带有构造函数的SomeData类(不带def值)之后,notNullableValue的值==NULL。 据我所知,在Kotlin中不是可空值可

  • 我们知道我们可以将null赋给可为null的类型。例如: 我们知道第二种说法是有效的,因为有人告诉我们它是有效的,我们只是接受它,而不问为什么。但如果查看的源代码,则为: 我们可以将赋给为的原因是由于隐式运算符,它允许您隐式强制转换int为。根据隐式运算符的规则,作为的右手边,必须是结构类型,但显然不是合法的结构值,那么如何做(更不用说本身就是一个结构),为什么不违反隐式运算符规则

  • 我不明白为什么在Kotlin的类外写函数是可能的?这是个好做法吗?

  • 问题内容: 我不明白为什么可以在Kotlin的类外编写函数?这是一个好习惯吗? 例如,在Kotlin中可以在我的课外编写一个函数: 在Java中,这是不可能的!那不是面向对象语言正常工作的方式,对吗? 在文档中,他们讨论了经典函数的 局部 函数和在类或对象内部定义的函数的 成员函数 ,但是他们没有解释何时使用一个或另一个更好。 问题答案: 在Java中,这是不可能的!那不是面向对象语言正常工作的方

  • 定义不可变类的策略表明 所有字段都应该是最终字段。 对于ex: 为什么一定要最终决定? 因为我没有给出setter方法吗?它不能改变。谢谢。

  • 代码B是一个定制的回收视图apater,带有单选按钮。 mCustomAdapter 在 Code A 中的 fun methodA() 和 fun methodB() 中都发生了变化,因此 的引用也发生了变化,这意味着 val 属性 mySelectedIndex 从不同的地址获取值。 在我看来,val属性不能更改,为什么应用程序不会导致错误? 代码A 代码B 被改进的 我觉得代码DD和代码EE