簡體   English   中英

Java類型擦除 - 為什么我在查看字節碼時能看到類型?

[英]Java type erasure - why can I see the type when I look at the bytecode?

我試圖理解為什么不允許在類中編寫這兩個方法

 public bool plus(List<String>) {return true;}
 public bool plus(List<Integer>) {return true;}

我試圖弄清楚它與類型擦除有什么關系,但是當我反編譯以下代碼時

public class Test<T> {

   boolean plus2(List<T> ss) {return false;}
   boolean plus(List<String> ss) {return false;}
   boolean plus(Set<Integer> ss) {return false;}
}

當我用Java反編譯器(jd)反編譯它時,我得到了同樣的結果

即使我打印字節代碼,我也可以清楚地看到類型。
(看看那些聲明'但是確保在字節碼中刪除類型'的答案 ')

    Compiled from "Test.java"
    public class com.example.Test<T> {
    public com.example.Test();
            Code:
            0: aload_0
            1: invokespecial #1                  // Method java/lang/Object."<init>":()V
            4: return

            boolean plus2(java.util.List<T>);
            Code:
            0: iconst_0
            1: ireturn

            boolean plus(java.util.List<java.lang.String>);
            Code:
            0: iconst_0
            1: ireturn

            boolean plus(java.util.Set<java.lang.Integer>);
            Code:
            0: iconst_0
            1: ireturn
            }

您的編譯器需要能夠根據字節代碼中的信息檢查泛型類型信息。

Java 5.0+以字節代碼記錄通用信息,但它不會將其記錄在對象實例中。

例如,無法獲得此列表的泛型類型

 // list.getClass() is just ArrayList which doesn't record the generic type.
List list = new ArrayList<String>();

不過這樣做

// list.getClass() is not ArrayList
// list is an instance of a class which extends ArrayList<String>
List list = new ArrayList<String>() { };

ParameterizedType t = (ParameterizedType) list.getClass().getGenericSuperclass();
assert t.getRawType() == ArrayList.class;
assert t.getActualTypeArguments()[0] == String.class;

這是因為ArrayList的子類的字節代碼記錄了它的父類中使用的泛型。

注意:這也適用於字段,構造函數/方法參數作為返回類型,實際類型記錄在字節代碼中。

但是,這些都不意味着實例的泛型類型可用(盡管如果以字節代碼記錄,父類/接口的泛型類型可用。

暫無
暫無

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

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