泛型集合.mixin原始类型和泛型类型.整数 - >字符串 - 异常但字符串 - >整数运行良好

gst*_*low 3 java generics casting type-conversion type-erasure

我对两个代码片段感到困惑:

摘录1

    List list = new ArrayList();
    list.add("1");
    Iterator<Integer> iterator = list.iterator();
    System.out.println(iterator.next());
Run Code Online (Sandbox Code Playgroud)

此代码正常执行并输出1到控制台

摘录2

    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考试,不要混合原始类型和泛型;

use*_*ica 6

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实际来自迭代器,导致你看到的异常.