Cómo deserializar las classs de datos henetworkingados de Kotlin con Gson

En una aplicación para Android, necesito deserializar los datos de Json para las classs de datos de Kotlin, con un solo nivel de abstracción. Pero no tengo idea de colocar las properties correctas en los constructores.

Como una versión simple, digamos que tengo una forma:

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

con dos derivaciones

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

y

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

Entonces mi objective es no crear una instancia de Shape. Entonces, en lugar de eso, siempre deserializa sus derivaciones. Más tarde necesito manejar algunas properties de colección en otras classs como:

 val shapes: List<Shape> 

pero también tengo que saber el tipo derivado de cada elemento.

Cuando trato de deserializar el ejemplo dado con Gson

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

Siempre recibo una exception 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) 

¿Hay alguna posibilidad de deserializar estas classs correctamente sin escribir un Gson TypeAdapter personalizado o perder las ventajas de la class de datos?

Gracias

Tanto Shape como Square declaran los campos x e y . Una instancia de Square realmente almacena el valor de x y y dos veces. Para evitar esto, puede eliminar y del constructor Shape y declararlos como abstract . Lo mismo ocurre con Circle eg:

 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 ahora podrá serializar y deserializar con éxito los objects Circle y Square .

¿Estás seguro de que es un problema de Gson con las classs de datos? Debería funcionar correctamente, solo los campos que no admiten nulos pueden ser un problema.

Su error indica que tiene campos con el mismo nombre.
Si hay algún campo en particular que no desea include, debe anotarlo con @Transient

Si aún no puede convertir la class base a Kotlin, la anotación @Transient funcionó para mí.

 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) 
  • La expresión lambda no se usa
  • ¿Cuál es la solución adecuada para @BeforeAll en Kotlin?
  • Realm Nested Object sort
  • Campo anulable con getter no anulable
  • Modelo lleno con respuesta extra usando Rx
  • Kotlin para Android y classs internas finales estáticas
  • ¿Es posible ocultar variables del cierre de lambda?
  • Errores de Kotlin Runtime en operadores básicos
  • ¿Cómo burlarse de los methods estáticos en Kotlin?
  • Orden de datos de spring por function de Java
  • ¿Cuál es la diferencia entre dos conversiones de Long a ByteArray?