下面的代码在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 {}
}发布于 2020-03-11 18:56:50
实际上,它是Java8中的一个错误,它是在Java9-故障修复中修复的.在某些情况下,javac CHECKCAST指令被跳过。
如果您有兴趣,请考虑这两行代码:
Set<Car> set = new HashSet<>(); // line 11
set.add(getAnimal()); // line 12Java 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)表示已解析了命名的类、数组或接口类型。如果可以将对象转换为已解析的类、数组或接口类型,则操作数堆栈不变;否则,checkcast指令将抛出一个ClassCastException。
https://stackoverflow.com/questions/54334575
复制相似问题