Java类型泛型作为GSON的参数
在GSON中获取您要执行的操作的对象列表Java类型泛型作为GSON的参数,java,generics,gson,Java,Generics,Gson,在GSON中获取您要执行的操作的对象列表 Gson gson = new Gson(); Type token = new TypeToken<List<MyType>>(){}.getType(); return gson.fromJson(json, token); Gson-Gson=new-Gson(); Type token=new-TypeToken(){}.getType(); 返回gson.fromJson(json,令牌); 它工作得很好,但我想更进
Gson gson = new Gson();
Type token = new TypeToken<List<MyType>>(){}.getType();
return gson.fromJson(json, token);
Gson-Gson=new-Gson();
Type token=new-TypeToken(){}.getType();
返回gson.fromJson(json,令牌);
它工作得很好,但我想更进一步,将MyType参数化,这样我就可以有一个公共函数来解析使用此代码的对象列表
// the common function
public <T> List<T> fromJSonList(String json, Class<T> type) {
Gson gson = new Gson();
Type collectionType = new TypeToken<List<T>>(){}.getType();
return gson.fromJson(json, collectionType);
}
// the call
List<MyType> myTypes = parser.fromJSonList(jsonString, MyType.class);
//公共函数
来自JSONList的公共列表(字符串json,类类型){
Gson Gson=新的Gson();
Type collectionType=new-TypeToken(){}.getType();
返回gson.fromJson(json,collectionType);
}
//电话
List myTypes=parser.fromJSonList(jsonString,MyType.class);
遗憾的是,返回的是StringMaps数组,而不是类型。T被解释为另一个泛型类型,而不是my类型。有什么解决方法吗?泛型在编译时工作。超级类型标记之所以有效,是因为(匿名)内部类可以访问其泛型超类(超级接口)的类型参数,而泛型超类(超级接口)又直接存储在字节码元数据中 编译.java源文件后,类型参数
显然会被丢弃。由于在编译时它是未知的,所以它不能存储在字节码中,所以它被擦除,Gson无法读取它
更新
在newacct回答之后,我尝试实现他在选项2中提出的建议,即实现参数化类型
。代码如下所示(这里是一个基本代码):
即使这项技术可行,而且确实非常聪明(我不知道,也从未想过),这也是最终的成就:
List<Integer> list = new Factory<Integer>()
.getFromJsonList(text, Integer.class)
List List=新工厂()
.getFromJsonList(文本,整数.class)
而不是
List<Integer> list = new Gson().fromJson(text,
new TypeToken<List<Integer>>(){}.getType());
List List=new Gson().fromJson(文本,
新的TypeToken(){}.getType());
对我来说,所有这些包装都是无用的,即使我同意
TypeToken
s会让代码看起来很糟糕:p泛型在编译时工作。超级类型标记之所以有效,是因为(匿名)内部类可以访问其泛型超类(超级接口)的类型参数,而泛型超类(超级接口)又直接存储在字节码元数据中
编译.java源文件后,类型参数
显然会被丢弃。由于在编译时它是未知的,所以它不能存储在字节码中,所以它被擦除,Gson无法读取它
更新
在newacct回答之后,我尝试实现他在选项2中提出的建议,即实现参数化类型
。代码如下所示(这里是一个基本代码):
即使这项技术可行,而且确实非常聪明(我不知道,也从未想过),这也是最终的成就:
List<Integer> list = new Factory<Integer>()
.getFromJsonList(text, Integer.class)
List List=新工厂()
.getFromJsonList(文本,整数.class)
而不是
List<Integer> list = new Gson().fromJson(text,
new TypeToken<List<Integer>>(){}.getType());
List List=new Gson().fromJson(文本,
新的TypeToken(){}.getType());
对我来说,所有这些包装都是无用的,即使我同意
TypeToken
s会让代码看起来很糟糕:p这已经在前面的问题中得到了回答。基本上有两种选择:
类型
。调用代码将使用TypeToken
或任何构造它的东西类型
。这将要求您编写一个实现ParameterizedType
这已经在前面的问题中得到了回答。基本上有两种选择:
类型
。调用代码将使用TypeToken
或任何构造它的东西类型
。这将要求您编写一个实现ParameterizedType
public class GenericOf<X, Y> implements ParameterizedType {
private final Class<X> container;
private final Class<Y> wrapped;
public GenericOf(Class<X> container, Class<Y> wrapped) {
this.container = container;
this.wrapped = wrapped;
}
public Type[] getActualTypeArguments() {
return new Type[]{wrapped};
}
public Type getRawType() {
return container;
}
public Type getOwnerType() {
return null;
}
}
public类GenericOf实现参数化类型{
私有最终类容器;
私人期末班;
公共GenericOf(类容器,类包装){
this.container=容器;
this.wrapped=wrapped;
}
公共类型[]getActualTypeArguments(){
返回新类型[]{wrapped};
}
公共类型getRawType(){
返回容器;
}
公共类型getOwnerType(){
返回null;
}
}
我将该方法向前推进了一步,并对该类进行了泛化,使其适用于每个类A,其中B是一个非参数化类。可能对集合和其他集合有用
public class GenericOf<X, Y> implements ParameterizedType {
private final Class<X> container;
private final Class<Y> wrapped;
public GenericOf(Class<X> container, Class<Y> wrapped) {
this.container = container;
this.wrapped = wrapped;
}
public Type[] getActualTypeArguments() {
return new Type[]{wrapped};
}
public Type getRawType() {
return container;
}
public Type getOwnerType() {
return null;
}
}
public类GenericOf实现参数化类型{
私有最终类容器;
私人期末班;
公共GenericOf(类容器,类包装){
this.container=容器;
this.wrapped=wrapped;
}
公共类型[]getActualTypeArguments(){
返回新类型[]{wrapped};
}
公共类型getRawType(){
返回容器;
}
公共类型getOwnerType(){
返回null;
}
}
由于gson 2.8.0
,您可以使用来创建typeToken
,然后getType()
应该完成这项任务
例如:
TypeToken.getParameterized(List.class, myType).getType();
由于
gson 2.8.0
,您可以使用来创建typeToken
,然后getType()
应该完成这项任务
例如:
TypeToken.getParameterized(List.class, myType).getType();
Kotlin为我提供的“列表”解决方案:
fun <T: Any> getGsonList(json: String, kclass: KClass<T>) : List<T> {
return getGsonInstance().fromJson<List<T>>(json, ListOfSomething<T>(kclass.java))
}
internal class ListOfSomething<X>(wrapped: Class<X>) : ParameterizedType {
private val wrapped: Class<*>
init {
this.wrapped = wrapped
}
override fun getActualTypeArguments(): Array<Type> {
return arrayOf<Type>(wrapped)
}
override fun getRawType(): Type {
return ArrayList::class.java
}
override fun getOwnerType(): Type? {
return null
}
}
fun getGsonList(json:String,kclass:kclass):列表{
返回getGsonInstance().fromJson(json,ListOfSomething(kclass.java))
}
某些内容的内部类列表(包装:类):ParameteredType{
私有类:类
初始化{
this.wrapped=wrapped
}
重写getActualTypeArguments():数组{
返回阵列(已包装)
}
重写getRawType():类型
class GenericGson {
companion object {
inline fun <reified T : Any> Gson.fromJsonTokenType(jsonString: String): T {
val type = object : TypeToken<T>() {}.type
return this.fromJson(jsonString, type)
}
inline fun <reified T : Any> Gson.fromJsonType(jsonString: String): T = this.fromJson(jsonString, T::class.java)
inline fun <reified T : Any> fromJsonTokenType(jsonString: String): T = Gson().fromJsonTokenType(jsonString)
inline fun <reified T : Any> fromJsonType(jsonString: String): T = Gson().fromJsonType(jsonString)
}
}
val arrayList = GenericGson.fromJsonTokenType<ArrayList<Person>>(json)
val places = getPlaces(Array<Place>::class.java)
public <T> List<T> fromJSonList(String json, Class<T> myType) {
Gson gson = new Gson();
Type collectionType = TypeToken.getParameterized(List.class, myType).getType();
return gson.fromJson(json, collectionType);
}
List<MyType> myTypes = parser.fromJSonList(jsonString, MyType.class);
public static <T> T getObject(String gsonStr) {
Gson gson = new GsonBuilder()
.setLenient()
.create();
Type collectionType = new TypeToken< T>(){}.getType();
return gson.fromJson(gsonStr,
collectionType);
}
Class1 class1= getObject(jsonStr);
CustomType type = new CustomType(Map.class, String.class, Integer.class);
class CustomType implements ParameterizedType {
private final Class<?> container;
private final Class<?>[] wrapped;
@Contract(pure = true)
public CustomType(Class<?> container, Class<?>... wrapped) {
this.container = container;
this.wrapped = wrapped;
}
@Override
public Type[] getActualTypeArguments() {
return this.wrapped;
}
@Override
public Type getRawType() {
return this.container;
}
@Override
public Type getOwnerType() {
return null;
}
}
inline fun <reified T> fromJson(json: String): T {
return Gson().fromJson(json, object: TypeToken<T>(){}.type)
}
val myTypes: List<MyType> = fromJson(jsonString);
public <T> List<T> fromJSonList(String json) {
Gson gson = new Gson();
Type collectionType = new TypeToken<List<T>>(){}.getType();
return gson.fromJson(json, collectionType);
}
//Just call
List<MyType> myTypes = parser.<MyType>fromJSonList(jsonString);