我對Gson和Json很新。我有簡單的事件,我想在Gson的幫助下通過Json序列化。Gson和序列化繼承對象的ArrayList
注意:代碼在Kotlin。
public abstract class Event() {
}
public class Move : Event() {
var from: Point? = null
var to: Point? = null
}
public class Fire : Event() {
var damage: Int = 0
var area: ArrayList<Point> = ArrayList(0)
}
public class Build : Event() {
var to: Point? = null
var type: String = ""
var owner: String = ""
}
我通過這種方式堅持這些一堆:
val list: ArrayList<Event>() = ArrayList()
list.add(move)
list.add(fire)
val str = gson.toJson(events)
而且unpersisting:
val type = object : TypeToken<ArrayList<Event>>(){}.getType()
val eventStr = obj.getString("events")
val events: ArrayList<Event> = gson.fromJson(eventStr, type)
我曾經嘗試都創建一個串行&解串器的事件類,和註冊它通過registerTypeAdapter,並且我也嘗試了RuntimeTypeAdapterFactory,但是它們都不會持久化需要的信息來取消正確的類型。
例如,RuntimeTypeAdapterFactory說: 「不能反序列化事件,因爲它並沒有定義一個名爲類型字段」
編輯:下面是「適配器」,這是..好,適應代碼從另一個StackOverflow的交:
public class Adapter :
JsonSerializer<Event>,
JsonDeserializer<Event> {
final val CLASSNAME = "CLASSNAME"
final val INSTANCE = "INSTANCE"
override fun serialize(src: Event?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement? {
val obj = JsonObject()
val className = (src as Event).javaClass.getCanonicalName()
obj.addProperty(CLASSNAME, className)
val elem = context!!.serialize(src)
obj.add(INSTANCE, elem)
return obj
}
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Event? {
val jsonObject = json!!.getAsJsonObject()
val prim = jsonObject.get(CLASSNAME)
val className = prim.getAsString()
val klass = Class.forName(className)
return context!!.deserialize(jsonObject.get(INSTANCE), klass)
}
}
此代碼失敗的NullPointerException上一行:
val className = prim.getAsString()
我想創建一個自定義的反序列化器是要走的路。你能發表你寫的代碼嗎? – rciovati
@RiccardoCiovati嗨,我添加了一些代碼。在序列化事件中沒有任何問題..但是,正如我所說的,當我反序列化時,信息根本就不存在(我打印了一個反序列化的Move事件,並且它只有Point數據爲「from」和「to」)(我也有Point-class的自定義序列化程序) – fluxi
傻了。我沒有註冊適用於子類的類型適配器,但只針對Event-class,這是問題所在。但是,現在我在線上有一個StackOverflowError:'val elem = context !!。serialize(src)'。任何想法可能會導致這種情況? – fluxi