我对两个代码段感到困惑:
List list = new ArrayList();
list.add("1");
Iterator<Integer> iterator = list.iterator();
System.out.println(iterator.next());
此代码正常执行并从1
退出到控制台
List list = new ArrayList();
list.add(1);
Iterator<String> iterator = list.iterator();
System.out.println(iterator.next());
结果 - RuntimeException
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
我很困惑,因为这两行都是错误的:
Integer integer = "123";
String string = 1;
这是编译错误。
为什么特异性行为不同?
P.S。
我准备参加scjp考试并且不要混合原始类型和泛型;
答案 0 :(得分:6)
PrintStream
,System.out
的类,有多个println
重载。特别是,它有an overload that takes an Object
和an overload that takes a String
。
在第一个例子中,
List list = new ArrayList();
list.add("1");
Iterator<Integer> iterator = list.iterator();
System.out.println(iterator.next());
编译器希望iterator.next()
生成Integer
,与此最匹配的是Object
版println
。编译器生成对方法的Object
版本的调用,这恰好适用于实际来自迭代器的String
。
在第二个例子中,
List list = new ArrayList();
list.add(1);
Iterator<String> iterator = list.iterator();
System.out.println(iterator.next());
编译器希望iterator.next()
生成String
,与此最匹配的是String
版println
。编译器生成对方法的String
版本的调用,并且由于类型擦除(使得运行时类型为iterator.next()
Object
),它会从{{1}生成运行时强制转换到Object
。对于实际来自迭代器的String
,此转换失败,导致您看到的异常。