簡體   English   中英

在 Java 泛型中不會拋出 ClassCastException

[英]No ClassCastException is thrown inside Java generics

下面是我寫過的第一個 Java 泛型:

public class MyClass {

    public static <T> T castToAnotherType(Object param) {
        T ret = null;
        try {
            ret = (T) param;
        } catch (ClassCastException e) {
            System.out.print("Exception inside castToAnotherType()");
        }
        return ret;
    }

    public static void main(String[] args) {
        try {
            String obj = MyClass.castToAnotherType(new Object());
        } catch (ClassCastException e) {
            System.out.print("Exception outside castToAnotherType()");
        }
    }

}

結果是“castToAnotherType() 之外的異常” 為什么泛型方法內部沒有發生異常?

T在編譯期間被有效地擦除。 這里

Java 語言中引入了泛型以在編譯時提供更嚴格的類型檢查並支持泛型編程。 為了實現泛型,Java 編譯器將類型擦除應用於:

  • 如果類型參數是無界的,則將泛型類型中的所有類型參數替換為其邊界或對象。 因此,生成的字節碼只包含普通的類、接口和方法。
  • 必要時插入類型轉換以保持類型安全。 生成橋接方法以保留擴展泛型類型中的多態性。
  • 類型擦除確保不會為參數化類型創建新類; 因此,泛型不會產生運行時開銷。

因此,您的castToAnotherTypeT擦除為 ca。 下列:

public static Object castToAnotherType(Object param) {
    Object ret = null;
    try {
        ret = (Object) param;
    } catch (ClassCastException e) {
        System.out.print("Exception inside castToAnotherType()");
    }
    return ret;
}

這顯然不會產生任何ClassCastException

main(...)是一個不同的故事,它的結果如下:

public static void main(String[] args) {
    try {
        String obj = (String) MyClass.castToAnotherType(new Object());
    } catch (ClassCastException e) {
        System.out.print("Exception outside castToAnotherType()");
    }
}

嘗試將ObjectString時會產生ClassCastException

請參閱泛型教程類型擦除部分。

好吧,由於編譯器刪除了泛型類型參數,方法內部的轉換本質上等同於:

    Object ret = null;
    try {
        ret = (Object) param;
    } 
    ...

這不是問題,無論您傳遞給方法的內容是什么(因為任何對象都可以轉換為對象)。

但是,當您嘗試將該 Object 分配給 String 時,在您的 main 方法中,會發生ClassCastException ,因為Object無法轉換為String

所有泛型類型都在編譯后的代碼中被擦除。 就編譯代碼而言, castToAnotherType只返回一個Object 但是,您的main方法嘗試將其分配給String ,而它不是String ,因此會產生ClassCastException

http://en.wikipedia.org/wiki/Type_erasure

這是因為泛型類型擦除,

       T ret = null;
       try {
            ret = (T) param;
...

被編譯器翻譯成

       Object ret = null;
       try {
            ret = (T) param;
...

暫無
暫無

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

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