为什么 Kotlin 数据类可以在 Gson 的不可空字段中具有空值? [英] Why Kotlin data classes can have nulls in non-nullable fields with Gson?

查看:30
本文介绍了为什么 Kotlin 数据类可以在 Gson 的不可空字段中具有空值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Kotlin 中你可以创建一个数据类:

In Kotlin you can create a data class:

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

然后您可以使用它来解析 JSON,例如{n: 10}".在这种情况下,您将有一个对象 val countries: CountryResponse,从 RetrofitFuelGson 接收,即包含以下值:count = 0,countries = null,error = null.

Then you can use it to parse a JSON, for instance, "{n: 10}". In this case you will have an object val countries: CountriesResponse, received from Retrofit, Fuel or Gson, that contains these values: count = 0, countries = null, error = null.

Kotlin + Gson -数据类为null时如何获取emptyList你可以看另一个例子.

In Kotlin + Gson - How to get an emptyList when null for data class you can see another example.

当你以后尝试使用 countries 时,你会在这里得到一个异常:val size = countries.countries.size: "kotlin.TypeCastException: null cannot be cast到非空类型 kotlin.Int".如果您编写代码并在访问这些字段时使用 ?,Android Studio 将突出显示 ?. 并警告:Unnecessary safe call on an non-null receiver of type列出<国家/地区>.

When you later try to use countries, you will get an exception here: val size = countries.countries.size: "kotlin.TypeCastException: null cannot be cast to non-null type kotlin.Int". If you write a code and use ? when accessing these fields, Android Studio will highlight ?. and warn: Unnecessary safe call on a non-null receiver of type List<Country>.

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

So, should we use ? in data classes? Why can an application set null to non-nullable variables during runtime?

推荐答案

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

This happens because Gson uses an unsafe (as in java.misc.Unsafe) instance construction mechanism to create instances of classes, bypassing their constructors, and then sets their fields directly.

请参阅此问答以进行一些研究:Gson Deserialization with Kotlin, 初始化块未调用.

See this Q&A for some research: Gson Deserialization with Kotlin, Initializer block not called.

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

As a consequence, Gson ignores both the construction logic and the class state invariants, so it is not recommended to use it for complex classes which may be affected by this. It ignores the value checks in the setters as well.

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

Consider a Kotlin-aware serialization solution, such as Jackson (mentioned in the Q&A linked above) or kotlinx.serialization.

这篇关于为什么 Kotlin 数据类可以在 Gson 的不可空字段中具有空值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆