GSON:无法反序列化(使用多个TypeAdapter)

时间:2019-04-23 18:57:57

标签: gson

我正在使用典型的InterfaceAdapter<T>

private class InterfaceAdapter<T : Any> : JsonSerializer<T>, JsonDeserializer<T> {
    override fun serialize(obj: T, interfaceType: Type, context: JsonSerializationContext): JsonElement {
        val wrapper = JsonObject()
        wrapper.addProperty("type", obj::class.java.name)
        wrapper.add("data", Gson().toJsonTree(obj))
        return wrapper
    }

    override fun deserialize(elem: JsonElement, interfaceType: Type, context: JsonDeserializationContext): T {
        val wrapper = elem as JsonObject
        val typeName = get(wrapper, "type")
        val data = get(wrapper, "data")
        val actualType = typeForName(typeName)
        return Gson().fromJson(data, actualType)
    }

    private fun typeForName(typeElem: JsonElement): Type {
        try {
            return Class.forName(typeElem.asString)
        } catch (e: ClassNotFoundException) {
            throw JsonParseException(e)
        }

    }

    private operator fun get(wrapper: JsonObject, memberName: String): JsonElement {
        return wrapper.get(memberName)
            ?: throw JsonParseException("no '$memberName' member found in what was expected to be an interface wrapper")
    }
}

我在几个课程中都这样注册:

private val gson = GsonBuilder()
    .registerTypeHierarchyAdapter(Inventory::class.java, InterfaceAdapter<Inventory>())
    .registerTypeHierarchyAdapter(Behaviour::class.java, InterfaceAdapter<Behaviour>())
    .registerTypeHierarchyAdapter(GameObject::class.java, InterfaceAdapter<GameObject>())
    .create()

当我检查调试序列化过程中发生了什么时,interfaceType仅是GameObject的实现,而不是BehaviourInventory的实现。尽管如此,序列化仍可顺利完成。然后,我尝试反序列化刚刚序列化的内容,并得到此异常:

java.lang.RuntimeException: Unable to invoke no-args constructor for interface [...].behaviour.Behaviour. Registering an InstanceCreator with Gson for this type may fix this problem.

以某种方式,当我删除GameObject的注册时,BehaviourInventory都被序列化(也就是说,我实际上可以看到interfaceType是它们在调试中的实现之一),但是当我重新添加时,突然只有GameObject被序列化。

那我该如何解决呢?

0 个答案:

没有答案