我有一些代码,我需要多次使用,所以我想把它放在一个方法中。代码是:
try
{
//Create a list descriptor for GSON to use
Type listType = new TypeToken<ArrayList<MyClass>>(){}.getType();
//Get it out as a list
List<MyClass> myClass = gson.fromJson( jsonString, listType );
}
catch (Exception e)
{
e.printStackTrace();
}
我把它放在一个方法中:
public static <T> List<T> getTypeAsList(String jsonString)
{
try
{
Gson gson = new Gson();
//Create a list descriptor for GSON to use
Type listType = new TypeToken<ArrayList<T>>(){}.getType();
//Get it out as a list
return gson.fromJson( jsonString, listType );
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
我将这种方法称为:
util.<MyClass>getTypeAsList( jsonString );
但是当我这样做时,我得到了错误:
com.google.gson.internal.StringMap cannot be cast to MyClass
为什么没有得到合适的类型?它适用于第一个代码,而不是通用方法。
答案 0 :(得分:3)
类型T
已被删除。这意味着通用方法没有T
的类型信息。
通常情况下,TypeToken
用于捕获该类型信息,但是实例化一个信息很简单,在您的情况下,您已经知道了一些信息,即您拥有{{1} 某些类型。
因此,您可以创建一个实用程序方法,以List
作为原始类型创建ParameterizedType
,并将任意ArrayList
作为类型参数:
Type
然后你可以像这样使用它:
public static ParameterizedType listTypeWith(Type t) {
Type[] actual = { t };
return new ParameterizedType() {
@Override
public Type getRawType() {
return ArrayList.class;
}
@Override
public Type getOwnerType() {
return null;
}
@Override
public Type[] getActualTypeArguments() {
return actual;
}
};
}
答案 1 :(得分:0)
这是由于编译时的类型擦除造成的。
进一步解释 - 在第一种情况下
new TypeToken<ArrayList<MyClass>>(){}
在编译时,将使用实际类型ArrayList<MyClass>
生成匿名类。另一方面,通用调用
new TypeToken<ArrayList<T>>(){}
实际编译的匿名类将接收ArrayList<Object>
作为实际类型。因此,gson使用默认实现(即StringMap
)来反序列化数组元素