2011-05-18 62 views
1

我想知道是否有使用語言特性泛型實現一個通用的容器之間在運行任何區別,介紹了Java 1.5,相比只有繼承和顯式類型轉換這樣做。如果有的話,哪個能夠提供最高的性能。Java泛型與oldstyle泛型的性能差異?

具體而言,可以說我有一個基類和子類:

public class Base { } 
public class Sub extends Base { } 

我在基類來定義一個容器類型。那麼我感興趣的是當容器實例已知包含某個子類時會發生什麼。 1.5之前,我沒有別的選擇,只能實現這樣的容器(不去管它過於簡單化,使實際意義):

public class OldstyleContainer { 
    private Base x; 

    public void set(Base x) { this.x = x; } 
    public Base get() { return x; } 
} 

及其用途類,其中已知元素的具體類型已知的可能看起來像這樣:

public Sub oldstylePut(OldstyleContainer c, Sub s) { 
    Sub t = (Sub) c.get(); 
    c.set(s); 
    return t; 
} 

現在,隨着語言特性的仿製藥,我反而這樣定義容器:

public class GenericsContainer<T extends Base> { 
    private T x; 

    public void set(T x) { this.x = x; } 
    public T get() { return x; } 
} 

以及相應的使用W烏爾德是這樣的:

public Sub genericsPut(GenericsContainer<Sub> c, Sub s) { 
    Sub t = c.get(); 
    c.set(s); 
    return t; 
} 

的通用版本的代碼看起來(非常)稍微簡單,因爲無需顯式類型轉換。但我的問題是,有沒有真正的區別在運行時,或者這是否投仍然在字節碼存在嗎?還有其他的區別嗎?

+1

編譯兩個版本,然後用'javap的-c'拆開他們看到的區別是在字節碼是什麼。 – Jesper 2011-05-18 10:11:32

+0

感謝您的建議!我自己應該想到這一點。我做到了,除了名字和評論外,他們完全一樣。還嘗試使用容器中的數組類型;相同的結果。 – njlarsson 2011-05-18 10:39:21

回答

3

泛型被擦除 - 所以在代碼運行的時候編譯器已經把變量放在了哪裏。使用泛型時,您無需親自在源代碼中執行操作。所以不要考慮性能 - 使用泛型來使代碼更安全。

3

沒有通用信息不可用在運行時,其唯一的編譯時間功能。

泛型是通過類型擦除來實現的:泛型類型信息僅在編譯時存在,之後被編譯器擦除。