类内部调用问题
来源:2-6 使用泛型
一轩明月
2019-07-06
老师您好,按照课程提示我自己编写了findAll与removeAll的实现,但是调用findAll时遇到下面的情形难以理解,需要帮助。
public int[] findAll(T ele){
Array<Integer> temp = new Array<>();
for(int i = 0; i < size; i++){
if(data[i].equals(ele)) {
temp.addToFirst(i);
}
}
if(temp.size != 0) {
int[] res = new int[temp.size];
for(int i = 0; i < temp.size; i++){
// res[i] = temp.data[i]; # ①不可行
res[i] = temp.get(i); # ②可行
}
return res;
}
return null;
}
我希望返回一个索引数组,但在赋值时发现①语句会报java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer提示类型转换出错,而②语句通过对象.方法获得索引处的值没有问题。
这背后的原因是什么呢,请教一下波波老师。
写回答
1回答
-
这还是一个挺tricky的问题,这也是我不很喜欢java的原因:)
整体来说,调用temp.data,会先将 temp.datav从Object[] 转成Integer[],这个操作是不被允许的。java语言在处理静态数组[]的时候,有各种限制。
注意,课程中的代码,在Array中,将 Object[] 转换成 E[] 是允许的。这二者不一样。一个在编译器处理的时候,只是类型占位符,编译器暂时"记住",继续下面的逻辑;另外一个,编译器要真刀真枪的把Object[]转换成Integer[],发现转换不了,失败。
但是,调用temp.get(i),在get内部,是取出E[]这个数组中的第i个元素,返回,返回的时候,是对某一个具体的元素,再转换成Integer,这是ok的。
一句话总结:这个错误的本质,和运行这句话,是一样的:
Integer[] arr = (Integer[])(new Object[100]);
你可以尝试一下,会报同样的错误。
所以,不要在Array的外面使用data,因为在外面无法把data具象化成任何类型:)
继续加油!:)
012019-07-06
相似问题