gst*_*low 3 java generics casting type-conversion type-erasure
我对两个代码片段感到困惑:
List list = new ArrayList();
list.add("1");
Iterator<Integer> iterator = list.iterator();
System.out.println(iterator.next());
Run Code Online (Sandbox Code Playgroud)
此代码正常执行并输出1到控制台
List list = new ArrayList();
list.add(1);
Iterator<String> iterator = list.iterator();
System.out.println(iterator.next());
Run Code Online (Sandbox Code Playgroud)
结果 - RuntimeException
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
Run Code Online (Sandbox Code Playgroud)
我很困惑,因为这两行都是错误的:
Integer integer = "123";
String string = 1;
Run Code Online (Sandbox Code Playgroud)
这是编译错误.
为什么特异性行为不同?
PS
我准备scjp考试,不要混合原始类型和泛型;
PrintStream,类System.out,有一些println重载.特别是,它有一个过载,需要一个Object和一个过载,需要一个String.
在第一个例子中,
List list = new ArrayList();
list.add("1");
Iterator<Integer> iterator = list.iterator();
System.out.println(iterator.next());
Run Code Online (Sandbox Code Playgroud)
编译器期望iterator.next()生成一个Integer,并且最好的匹配就是Object版本println.编译器生成Object对方法版本的调用,这恰好适用于String实际来自迭代器的方法.
在第二个例子中,
List list = new ArrayList();
list.add(1);
Iterator<String> iterator = list.iterator();
System.out.println(iterator.next());
Run Code Online (Sandbox Code Playgroud)
编译器期望iterator.next()产生一个String,并且最佳匹配就是String版本println.编译器生成String对方法版本的调用,并且由于类型擦除(使得运行时类型为iterator.next() Object),它会从中生成运行时强制Object转换String.这个转换失败的Integer实际来自迭代器,导致你看到的异常.