簡體   English   中英

為什么這段帶有泛型的代碼會在 Java 11 中拋出 ClassCastException?

[英]Why does this code with generics throw a ClassCastException in Java 11?

下面的代碼在 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 {}
}

實際上,這是 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 )聲明命名的類、數組或接口類型已解析。 如果 object 可以轉換為解析的類、數組或接口類型,則操作數堆棧不變; 否則,checkcast 指令會拋出 ClassCastException

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM