【发布时间】:2018-03-30 11:07:09
【问题描述】:
public static void main(String[] args) {
List<Integer> integers = new ArrayList<>();
integers.add(5); //element #0
List list = integers;
list.add("foo"); //element #1
integers.get(1); //no error
System.out.println(integers.get(1)); //no error, prints "foo"
Integer i = integers.get(1); //throws ClassCastException
}
我试图了解转换类型变量的过程,声明为泛型类型参数,我有点困惑。
因此,您可能会在我提供的示例中看到,在我们创建了一个非参数化的 List,它引用了与 List<Integer> 相同的对象之后,我们可以将任何对象添加到该列表中(好吧,没什么奇怪的这里)而且,让我非常困惑的是,我们可以从List<Integer> integers 中提取非Integer 值。为什么ClassCastException 没有在integers.get(1) 的第一次或第二次调用时抛出?
我假设返回参数类型的方法,实际上总是返回Object,并且那些返回值被隐式尝试转换为
运行时的左值类型或方法参数类型(因为运行时没有泛型),但是以下测试使我确信Integer 总是优于Object:
public static void main(String[] args) {
List<Integer> integers = new ArrayList<>();
integers.add(5); //element #0
List list = integers;
list.add("foo"); //element #1
print(integers.get(1));
}
private static void print(Object var) {
System.out.println(var);
}
//this method is entered
private static void print(Integer var) {
System.out.println(var);
}
private static void print(String var) {
System.out.println(var);
}
另一个有趣的事实是,虽然ArrayList 的元素存储在Object[] 数组中,但它们总是在返回到方法get() 之前转换为类型参数中定义的类型:
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
E elementData(int index) {
return (E) elementData[index];
}
所以,如果有人可以向我指出逐步解释这些问题的文档,我将非常感谢
【问题讨论】: