如何使用Gson反序列化继承的Kotlin数据类
在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)
我总是得到一个IllegalArgumentException
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 TypeAdapter或丢失数据类的优势?
谢谢
Shape
和Square
声明字段x
和y
。 Square
实例实际上将x
和y
的值存储两次。 为了避免这种情况,您可以从Shape
构造函数中移除x
和y
,并将它们声明为abstract
。 Circle
一样,例如:
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现在可以成功地对Circle
和Square
对象进行序列化和反序列化。
你确定这是数据类的Gson问题吗? 它应该与他们正确地工作,只有不可空字段可能是一个问题。
你的错误表明你有同名的字段。
如果您不想包含任何特定字段,则必须使用@Transient
对其进行注释
如果你现在还不能将基类转换成Kotlin,那么@Transient
注解对我@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)