Java集合ArrayList,LinkedList强制转换异常
我发现了一个至今无法解释的奇怪案例Java集合ArrayList,LinkedList强制转换异常,java,arraylist,collections,classcastexception,Java,Arraylist,Collections,Classcastexception,我发现了一个至今无法解释的奇怪案例 public static void main(String[] args) { LinkedList<Integer> a = new LinkedList<>(); a.add(2); a.add(3); a.add(4); for (ArrayList ax : getBatches(a)){ System.out.println(ax); } } priva
public static void main(String[] args) {
LinkedList<Integer> a = new LinkedList<>();
a.add(2);
a.add(3);
a.add(4);
for (ArrayList ax : getBatches(a)){
System.out.println(ax);
}
}
private static ArrayList<ArrayList<Integer>> getBatches(List<Integer> optionIds) {
return new ArrayList(Arrays.asList(optionIds));
}
publicstaticvoidmain(字符串[]args){
LinkedList a=新建LinkedList();
a、 增加(2);
a、 增加(3);
a、 增加(4);
对于(ArrayList ax:getBatches(a)){
系统输出打印LN(ax);
}
}
私有静态ArrayList getBatches(列表选项ID){
返回新的ArrayList(Arrays.asList(optionId));
}
执行的结果是:
线程“main”java.lang.ClassCastException中的异常:无法将java.util.LinkedList转换为java.util.ArrayList
异常进入for循环
问题是:如何?返回类型为ArrayList
ArrayList
,这就是编译器允许它的原因。但是,在运行时,会尝试将LinkedList
(传递给getBatches
方法的实例)强制转换为ArrayList
,从而导致ClassCastException
如果将方法更改为:
private static ArrayList<ArrayList<Integer>> getBatches(List<Integer> optionIds) {
return new ArrayList<>(Arrays.asList(optionIds));
}
这将返回一个ArrayList
,其单个元素是ArrayList
,包含与传递给方法的列表相同的元素。getBatches()
将返回一个泛型类型为ArrayList
的ArrayList。Arrays.asList()
的返回类型是一个List
接口。为了从列表到ArrayList,它需要进行隐式转换。问题是不能直接将ArrayList强制转换为LinkedList
解决这个问题相对简单。不要遍历ArrayList
s,而是遍历List
s。e、 g.for(列表l:getBatches(a)
。然后只需制作getBatches()
returnArrayList
一般来说,您需要尽可能使用最抽象的东西。如果您不需要ArrayList
的特定于实现的详细信息,只需将其称为列表即可。这是使用的结果
通过调用new ArrayList(…)
而不指定ArrayList
的泛型参数T
,您使用的是原始类型ArrayList
上面链接的文档说:
但如果将原始类型分配给参数化类型,则会得到
警告:
Eclipse显示以下与新ArrayList(Arrays.asList(optionId))相关的警告;
:
类型安全性:类型ArrayList
的表达式需要取消选中
转换为符合ArrayList
因此,将原始类型的ArrayList
返回为ArrayList
,不会导致编译时错误
getBatches(a)
的结果类型为ArrayList
。此类型列表的元素类型为ArrayList
。使用原始类型ArrayList
将它们分配给ax
,也没有编译时错误
为了向后兼容,将参数化类型指定给其原始
类型是允许的:
但是在运行时,当涉及到将
getBatches(a)
元素强制转换为ArrayList
时,忽略警告会导致ClassCastException
,因为运行时类型LinkedList
无法强制转换为ArrayList
(此时已删除泛型类型)。
private static ArrayList<ArrayList<Integer>> getBatches(List<Integer> optionIds) {
return new ArrayList<>(Arrays.asList(new ArrayList<>(optionIds)));
}