2017-04-23 96 views
3

在Android應用程序中,我需要爲具有單個抽象級別的Kotlin數據類反序列化Json數據。但我沒有任何想法,在構造函數中放置正確的屬性。如何使用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) 

我總是得到一個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或鬆動數據類優勢?

謝謝

回答

1

你確定這是數據類的Gson問題嗎?它應該正確地使用它們,只有不可空字段可能是一個問題。

您的錯誤表明您的字段中有相同的名稱。
如果有您不希望包括你有@Transient

5

兩個ShapeSquare註釋任何特定字段聲明字段xySquare的一個實例實際上存儲了兩次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)