ArrayList包含错误的类型对象,没有显式的原始类型转换

时间:2014-11-12 10:57:07

标签: java android generics type-safety gson

任何人都可以建议给定代码如何可能导致此类问题,并在从文件中解析数据时偶尔提供ClassCastException

详细信息:

我在超类中有一个泛型方法。

public T getItem(int position) {
     return mItems.get(position); // mItems is an ArrayList
}
// corresponding setter
public void setItems(List<T> items) {
    mItems = items;
    notifyDataSetChanged();
}

然后在子类中使用T = AdItem,如下所示:

AdItem adItem = getItem(position);

一切正常,但我偶尔会收到生产崩溃报告,但上述行没有例外:

java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to .mypackage.AdItem

这显然表明该列表包含LinkedTreeMap而不是AdItem

该列表是从json解析的,代码是类型安全的,即没有原始类型转换,未经检查的警告等。

ArrayList<AdItem>包含LinkedTreeMap个对象运行时的方案是什么?
除了明确的未经检查/原始类型转换为Object并返回ArrayList,情况并非如此。

从文件解析json:

ArrayList<AdItem> tempList = gson.fromJson(jsonReader, typeToken.getType());

其中

typeToken = new TypeToken<ArrayList<AdItem>>() {};

所以tempList应该只包含AdItem

任何人都可以解释上面的代码可能会发生ClassCastException吗?任何额外的细节将根据要求提供。

1 个答案:

答案 0 :(得分:1)

默认情况下,如果JSON对象无法正确识别提供的类型,则会将其反序列化为LinkedHashMap。

使用下面的代码获取类型,然后重试:

TypeFactory.defaultInstance().constructCollectionType(ArrayList.class,AdItem.class)

or

new ObjectMapper().getTypeFactory().constructCollectionType(ArrayList.class,AdItem.class) // In case you are using ObjectMapper

ArrayList<AdItem> tempList = gson.fromJson(jsonReader, TypeFactory.defaultInstance().constructCollectionType(ArrayList.class,AdItem.class));