使用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 
Interesting Posts