2017-04-23 83 views
3

Android App에서는 하나의 추상화 수준으로 Kotlin 데이터 클래스의 Json 데이터를 deserialize해야합니다. 하지만 생성자에 올바른 속성을 추가 할 생각은 전혀 없습니다.Gson을 사용하여 상속 된 Kotlin 데이터 클래스를 역 직렬화하는 방법

간단한 버전으로

, 이제 나는 모양 있다고 가정 해 봅시다 :

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) 

을 주어진 예제를 역 직렬화 할 때 나는 항상이 클래스를 직렬화 할 가능성이 사용자 정의 GSON TypeAdapter를 작성하거나 잃어버린없이 정확하게 거기는 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) 

를 얻을 수 데이터 클래스 장점?

감사합니다.

답변

1

데이터 클래스에 Gson 문제가 있습니까? 그것들은 올바르게 작동해야하며, null이 아닌 필드 만 문제가 될 수 있습니다.

오류는 동일한 이름의 필드가 있음을 나타냅니다.
당신이 @Transient

5

모두 ShapeSquare 함께 주석이 포함하지 않는 특정 분야가 있다면이 필드를 xy을 선언합니다. Square의 인스턴스는 실제로 xy의 값을 두 번 저장합니다. 이를 방지하려면 Shape 생성자에서 xy을 제거하고 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가 성공적으로 직렬화 및 CircleSquare 객체를 역 직렬화 할 수있을 것입니다.

+1

감사합니다. 이것이 제가 찾던 해결책입니다. – elcolto

1

기본 클래스를 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)