【问题标题】:generics collections.mixin raw and generic type. Integer -> String - exception but String -> Integer works goodgenerics collections.mixin 原始和泛型类型。 Integer -> String - 异常,但 String -> Integer 效果很好
【发布时间】:2014-06-03 19:43:48
【问题描述】:

我对两个代码 sn-ps 感到困惑:

sn-p 1

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

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

sn-p 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;

这是编译错误。

为什么同类行为不同?

附言

我正在准备 scjp 考试,不要混合使用原始类型和泛型;

【问题讨论】:

  • 类型擦除。您的第一个示例是原始类型。
  • @ElliottFrisch:与第二个示例相同。
  • @ElliottFrisch:没有什么能阻止它。盒装整数与任何其他对象一样具有 toString。
  • @Elliott Frisch 我不明白你
  • 尝试在上面运行javap

标签: java generics casting type-conversion type-erasure


【解决方案1】:

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,最匹配的是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),它生成从ObjectString 的运行时转换。对于实际上来自迭代器的Integer,此转换失败,导致您看到的异常。

【讨论】:

  • 这真是一个很难的例子。但解释看起来是对的。
  • 所以问题出在 ``System.out.println()` 而不是iterator.next()。很好的答案。
猜你喜欢
  • 2014-12-02
  • 2019-09-10
  • 1970-01-01
  • 2019-05-05
  • 2011-09-22
  • 2013-06-20
  • 1970-01-01
  • 2013-03-01
  • 1970-01-01
相关资源
最近更新 更多