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

如何使用Gson反序列化继承的Kotlin数据类

邢博文
2023-03-14

在Android应用程序中,我需要用一个抽象级别反序列化Kotlin数据类的Json数据。但我不知道如何在构造函数中放置正确的属性。

简单来说,假设我有一个形状:

abstract class Shape(open val x: Int, open val y: Int)

有两个派生

data class Circle(val radius: Int, override val x: Int, override val y: Int): Shape(x, y)

data class Square(val width: Int, override val x: Int, override val y: Int): Shape(x, y)

所以我的目标是,不要实例化一个形状。所以,相反,总是反序列化它的派生。稍后,我需要处理其他类中的一些集合属性,如:

val shapes: List<Shape>

但我还必须知道每个元素的派生类型。

当我尝试用Gson反序列化给定的示例时

val square = gson.fromJson(SQUARE_JSON, Square::class.java)

我总是有一个非法的辩论例外

java.lang.IllegalArgumentException: class com.example.shapes.model.Square declares multiple JSON fields named x

at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:170)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:100)
at com.google.gson.Gson.getAdapter(Gson.java:423)
at com.google.gson.Gson.fromJson(Gson.java:886)
at com.google.gson.Gson.fromJson(Gson.java:852)
at com.google.gson.Gson.fromJson(Gson.java:801)
at com.google.gson.Gson.fromJson(Gson.java:773)

有没有可能在不编写自定义Gson类型适配器或失去数据类优势的情况下正确反序列化这些类?

谢谢

共有3个答案

薛泰
2023-03-14

你确定这是数据类的Gson问题吗?它应该正确地使用它们,只有不可为空的字段可能是个问题。

您的错误表明其中有同名字段
如果您不想包含任何特定字段,则必须使用@Transient

仰雅昶
2023-03-14

如果您还不能将基类转换为Kotlin,那么@Transient注释对我来说很有用。

data class Circle(val radius: Int, 
    @Transient val x: Int, 
    @Transient val y: Int): Shape(x, y)

data class Square(val width: Int, 
    @Transient val x: Int, 
    @Transient val y: Int): Shape(x, y)
江宏深
2023-03-14

ShapeSquare都声明字段xySquare的一个实例实际上存储了xy的值两次。为了避免这种情况,您可以从Shape构造函数中删除xy,并将它们声明为abstract。这同样适用于圆圈,例如:

abstract class Shape {
    abstract val x: Int
    abstract val y: Int
}

data class Circle(val radius: Int, override val x: Int, override val y: Int) : Shape()

data class Square(val width: Int, override val x: Int, override val y: Int) : Shape()

Gson现在将能够成功地序列化和反序列化CircleSquare对象。

 类似资料:
  • 我有一个简单的Json结构,比如: 我设计了以下类来反序列化它: 我需要将反序列化分为两个阶段: 1-反序列化以读取。 2.2基于MessageType进行其余的反序列化 代码很简单: 我的程序可以输入正确的(即),但它不能正确解析它(println打印0而不是12) 你觉得我哪里做错了?谢谢你们

  • 问题内容: 我在反序列化以下json数组时遇到麻烦(对不起,大小): 如果将其粘贴到json-viewer中,则会得到以下结构: 现在,包含具有坐标的数组的数组具有可变大小。所以我想在Java中,整个对象应该是一个数组,其中包含数组的集合,每个数组都包含一个。就像是 但是gson不接受这一点。我收到以下错误消息: 这似乎很奇怪,因为对我来说好像不像一个数组。但这可能使我感到困惑,或多或少地迷路了…

  • 问题内容: 我使用了很多不可变的集合,并且很好奇如何使用Gson反序列化它们。由于没有人回答,而且我自己找到了解决方案,因此我正在简化问题并提出自己的答案。 我有两个问题: 如何为所有人编写一个作品? 如何全部注册? 问题答案: 更新:有https://github.com/acebaggins/gson- serializers ,其中涵盖了许多番石榴集合: 如何编写适用于所有Immutable

  • 我面临一个生成器类继承的序列化问题。如下所示: 基类: 我看到以下例外: 有人知道如何避免这个问题吗?

  • 我需要序列化/反序列化特定枚举: 我有个例外: 我如何通过GSON序列化/反序列化它?

  • 问题内容: 我正在尝试仅使用json.net序列化类的继承属性。我知道[JsonIgnore]属性,但是我只想在某些情况下忽略它们,因此我改用了自定义JsonConverter。 这是我的课: 做一个简单的o.WriteTo(writer); 它给出的结果与不使用转换器的结果相同。当遍历属性并在属性上使用WriteTo时,它对于基本类型(int,字符串等)正常工作,但是集合存在问题。 预期: 得到