泛型集合.mixin原始类型和泛型类型。整数 - >字符串 - 例外但字符串 - >整数运作良好

时间:2014-06-03 19:43:49

标签: 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());

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

摘录2

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

1 个答案:

答案 0 :(得分:6)

PrintStreamSystem.out的类,有多个println重载。特别是,它有an overload that takes an Objectan 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,与此最匹配的是Objectprintln。编译器生成对方法的Object版本的调用,这恰好适用于实际来自迭代器的String

在第二个例子中,

List list = new ArrayList();
list.add(1);
Iterator<String> iterator = list.iterator();
System.out.println(iterator.next());

编译器希望iterator.next()生成String,与此最匹配的是Stringprintln。编译器生成对方法的String版本的调用,并且由于类型擦除(使得运行时类型为iterator.next() Object),它会从{{1}生成运行时强制转换到Object。对于实际来自迭代器的String,此转换失败,导致您看到的异常。