使用gson序列化和返回不适用于泛型类型
我正在编程一个kotlin websocket,并想发送转换为json与gson的dtos。 所以我写了一个包装dto包含真正的dto和dto的一些额外的信息,就像它的类型。 这是我的包装dto
class WrapperDto <T : AbstractDto> { var type = "" var action = "" var dto : T = AbstractDto() as T }
这是它可以包含的dtos之一:
class Person : AbstractDto() { var firstName = "" var familyName = "" }
在这里出于测试的原因,我尝试将其转换为json然后再转换回来:
val wrapperDto2 = WrapperDto<Person>() wrapperDto2.type = Person::class.simpleName!!; wrapperDto2.action = "add" val person = Person() person.firstName = "Richard" person.familyName = "Lederer" wrapperDto2.dto = person; val gson1 = Gson() val toJson = gson1.toJson(wrapperDto2) println("to json: " + toJson) val fromJson = gson1.fromJson(toJson, wrapperDto2::class.java) println("from json: " + fromJson)
最后一个println从来没有被调用,我得到以下错误信息:
java.lang.IllegalArgumentException: Can not set at.richardlederer.contactmanager.dto.AbstractDto field at.richardlederer.contactmanager.dto.WrapperDto.dto to com.google.gson.internal.LinkedTreeMap at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
我该如何解决这个问题?
这是由于类型擦除 泛型 。 您需要使用TokenType
在运行时检索类型信息。
val fromJson = gson1.fromJson<WrapperDto<Person>>(toJson, object: TypeToken<WrapperDto<Person>>() {}.type)
你也可以像这样创建一个扩展函数:
inline fun <reified T> fromJson(json: String): T = Gson().fromJson<T>(json, object: TypeToken<T>() {}.type)
那么,你可以这样叫fromJson
:
val fromJson = fromJson<WrapperDto<Person>>(toJson) //Or val fromJson: WrapperDto<Person> = fromJson(toJson) //Type inferred