java之为什么这个带有泛型的代码会在 Java 11 中引发 ClassCastException
虾米哥
阅读:40
2024-06-20 12:54:19
评论:0
下面的代码在 Java 8 中成功,但在 Java 11 中抛出 ClassCastException。为什么行为会发生变化?
我在 OpenJDK 的 Java 9、Java 10 或 Java 11 功能集中找不到任何相关更改。
public class GenericsExample {
public static void main(String[] args) {
Set<Car> set = new HashSet<>();
set.add(getAnimal());
}
static <T extends Animal> T getAnimal() {
return (T) new Animal() {};
}
interface Animal {}
class Car {}
}
请您参考如下方法:
确实是 bug在 Java 8 中,已在 Java 9 中修复 - bugfix .
在某些情况下,javac CHECKCAST
指令被跳过。
如果您好奇,请考虑以下两行代码:
Set<Car> set = new HashSet<>(); // line 11
set.add(getAnimal()); // line 12
Java 8 字节码将如下所示:
LINENUMBER 11 L1
ALOAD 1
ALOAD 0
INVOKEVIRTUAL UserManagerTest.getAnimal ()LUserManagerTest$Animal;
INVOKEINTERFACE java/util/Set.add (Ljava/lang/Object;)Z (itf)
POP
但是 Java 9 看起来像这样:
LINENUMBER 11 L1
ALOAD 1
ALOAD 0
INVOKEVIRTUAL UserManagerTest.getAnimal ()LUserManagerTest$Animal;
CHECKCAST UserManagerTest$Car
INVOKEINTERFACE java/util/Set.add (Ljava/lang/Object;)Z (itf)
POP
唯一的区别是
CHECKCAST
指令,(根据
JavaDoc )声明命名的类、数组或接口(interface)类型已解析。如果 object 可以转换为已解析的类、数组或接口(interface)类型,则操作数堆栈不变;否则,checkcast 指令会抛出 ClassCastException。
声明
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。