下面的代码在 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。
关于java - 为什么这个带有泛型的代码会在 Java 11 中引发 ClassCastException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54334575/