【发布时间】:2011-04-22 07:31:33
【问题描述】:
下面代码中什么情况下会出现ClassCastException:
import java.util.Arrays;
import java.util.List;
public class Generics {
static List getObjects() {
return Arrays.asList(1, 2, 3);
}
public static void main(String[] args) {
List<String> list = getObjects();
for (Object o : list) { // ClassCastException?
System.out.println(o);
}
}
}
我们在生产环境中遇到过类似的情况(我知道这是不好的做法),客户在注释行提供了带有 ClassCastException 的日志,但我似乎无法重现它。有什么想法吗?
我知道 JVM 在使用 foreach 时会在后台创建一个迭代器,但它可以在某些情况下创建一个原始迭代器,而在其他情况下创建一个参数化的迭代器吗?
更新:我还查看了在 Windows 上生成的字节码,使用 JDK 1.6.0_21-b07 no checkcast 制作完成。有趣:)
这里是主要方法:
公共静态无效主(java.lang.String[]); 代码: 0:调用静态#34; //方法getObjects:()Ljava/util/List; 3:astore_1 4:aload_1 5: 调用接口#36, 1; //接口方法 java/util/List.iterator:()Ljava/util/Iterator; 10:astore_3 11:转到 28 14:加载_3 15: 调用接口#42, 1; //接口方法 java/util/Iterator.next:()Ljava/lang/Object; 20:astore_2 21:获取静态#48; //字段 java/lang/System.out:Ljava/io/PrintStream; 24:加载_2 25:调用虚拟#54; //方法java/io/PrintStream.println:(Ljava/lang/Object;)V 28:加载_3 29: 调用接口#60, 1; //接口方法 java/util/Iterator.hasNext:()Z 34:如果 14 37:返回感谢大家的回答!
更新 2:我被使用 own compiler 的 Eclipse IDE 误导了,所以实际上它上面的字节码是使用 Eclipse 编译器生成的。看here如何用Eclipse手动编译代码。 总之,Eclipse 编译器在某些情况下会生成与 Sun 编译器不同的字节码,与平台无关,这里描述的情况是一种。
【问题讨论】:
-
Java 泛型正在咬你! ;-)
-
提示:(1) 使用您可以使用的所有信息 - 异常应该告诉您涉及哪些类,例如
java.lang.ClassCastException: XXXX cannot be cast to YYYY。 (2) 行号有时会偏离几行,因此请查看报告行上方和下方的几行,以了解可能的异常来源。 -
确实,给出确切的信息。
-
上面的代码是生产代码的模仿,但“翻译”错误是 ClassCastException Integer cannot be cast to String
-
感谢您发布反汇编。
checkcast出现在某些编译版本中(我的,Tim 使用 1.6.0_21 时的版本)而不是其他版本(bozho 的,你的),这很有趣……
标签: java generics iterator foreach classcastexception