2012-12-29 141 views
4

我發現以下問題並回答Oracle網站爪哇 - 泛型類型 - 類型擦除

是什麼類型擦除後轉換爲下面的類呢?

public class Pair<K, V> { 

    public Pair(K key, V value) { 
     this.key = key; 
     this.value = value; 
    } 

    public K getKey(); { return key; } 
    public V getValue(); { return value; } 

    public void setKey(K key)  { this.key = key; } 
    public void setValue(V value) { this.value = value; } 

    private K key; 
    private V value; 
} 

答:

public class Pair { 

    public Pair(Object key, Object value) { 
     this.key = key; 
     this.value = value; 
    } 

    public Object getKey() { return key; } 
    public Object getValue() { return value; } 

    public void setKey(Object key)  { this.key = key; } 
    public void setValue(Object value) { this.value = value; } 

    private Object key; 
    private Object value; 
} 

但是,當我使用反編譯JD-GUI的類文件,我仍然可以看到所有類似的泛型類型我有什麼實際的源代碼。

這是否意味着泛型類型保留在類文件中?我正在使用Java 6.

使用JD-GUI的類的反編譯器版本如下。我使用Eclipse Helios編譯該類。

public class Pair<K, V> 
{ 
    private K key; 
    private V value; 

    public Pair(K key, V value) 
    { 
    this.key = key; 
    this.value = value; 
    } 
    public K getKey() { 
    return this.key; } 
    public V getValue() { return this.value; } 
    public void setKey(K key) { 
    this.key = key; } 
    public void setValue(V value) { this.value = value; 
    } 
} 
+0

你是如何編譯這些類的?調試信息可能包含在某些編譯器選項中。 – madth3

+0

我正在使用eclipse。所以,它會自動編譯這些類。然後我使用JD-GUI工具來反編譯類文件。 – Jack

回答

6

一些通用型信息保留在.class文件 - 足以讓你來決定,通過反射,該類型對是通用的,並且具有對成員的類,什麼類型的一般的參數等等。保留這些信息的事實形成了像super type tokens這樣的技術的基礎,它允許你傳遞保留有關其通用參數信息的類型標記。

然而,除了反射之外,類型擦除意味着Pair類大部分將按照Oracle網站的「答案」中的剝離版本行事。特別是,這些方法的實際字節碼將不會引用泛型類型KV - 僅對象,並且方法簽名將接受並返回Object

在這種情況下,JD-GUI只是很聰明,並且使用存儲在.class文件中的信息來恢復反編譯輸出中的通用信息,但是確保類型在字節碼中被擦除。

+0

感謝您的及時迴應。我已經閱讀了關於具有泛型類型的反射。我讀到類簽名包含通用類型信息。有一件事我不明白的是這個「**方法的實際字節碼將不會引用泛型類型K或V - 僅對象**」。那麼,該類的反編譯版本是錯誤的,這與源代碼完全相似?在JD-GUI中顯示如下: public class Pair { private K key;私人V值爲 ; ................ – Jack

+1

也許這會幫助你發佈反編譯後的版本。 我的意思是字節碼將操縱'對象'不是K或V(它們不是具體的類型)。這可能是因爲你的反彙編程序很好,並且使用類文件中記錄的通用信息來顯示泛型類型,但是字節碼本身不會反映(例如,不會出現到'(V)'的轉換在字節碼中)。 – BeeOnRope

+0

替代措辭:字節碼知道有一個名爲'K'的變量,但是在運行時,如果您有'Pair ','K'將不會是'String' - 它只會是'Object'。 –