How to deserialize inherited Kotlin data classes using Gson

In an Android app, I need to deserialize Json data for Kotlin data classes with one level of abstraction. But I have no idea to put the correct properties in the constructors.

As a simple version, let's say I have a Shape:

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

with two conclusions

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

and

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

So my goal is not to instantiate the form. So, instead, always deserialize your findings. Later I need to handle some properties of the collection in other classes, for example:

val shapes: List<Shape>

but I also need to know the derived type of each element.

When I try to deserialize this example using Gson

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

I always get 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)

, GScript TypeAdapter ?

+4
3

Shape Square x y. Square x y . , x y Shape 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.

+6

, Gson ? , , .

, .
- , , @Transient

+1

If you have not yet been able to convert the base class to Kotlin, the annotation worked for me @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)
+1
source

Source: https://habr.com/ru/post/1675465/


All Articles