2011-07-02 118 views
0

當談到橋接方法時,我知道java編譯器會在需要時添加它們,以便覆蓋可以由子類正確完成(在通過mughal和angelikalanger網站閱讀SCJP之後)。但是,這是一個有點混亂按如下:Java泛型 - 橋接方法

擦除之前:

class x <T> { 
    void set(T t){} 
} 

class y <E> extends x { 
    void set(E e) {} // name clash here 
} 

class z<E> extends x { 
    void set(Object y) {} // no name clash here 
} 

class z1<E> extends x<T> { 
    void set(Object y) {} // name clash here 
} 

擦除後:

class x { 
    void set (Object t) {} 
} 

我理解的名稱衝突的Y級,但爲什麼沒有名稱衝突的z類? 也有類z1的名稱衝突?令人費解的

+0

'類z'覆蓋''類x'的set'方法。 E型和T型不完全相同。所以名稱衝突'類z1' –

+0

只是一個建議:不要使用原始類型,特別是不能從它們延伸。 –

+0

收到您的國旗,對不起 - 不能按要求做。 –

回答

1

正如你所說,擦除後的設置方法需要一個對象。 z擴展了非泛型,擦除後發生x

2
class y <E> extends x { 
    void set(E e) {} // name clash here 
} 

這裏名稱衝突,因爲E不是T的子類,所以你不能覆蓋set方法本way.see解釋爲Z1,以更好地理解。 對於Y類的工作,你必須有

class y <E> extends x<E> { 
    void set(E e) {} 
} 

下一頁:

class z<E> extends x { 
    void set(Object y) {} // no name clash here 
} 

這裏沒有名稱衝突,因爲在類X,設置方法被解釋爲

void set(java.lang.Object) 

並且在類z中set的參數是java.lang.Object.so no clash。

下一頁:發生

class z1<E> extends x<T> { 
    void set(Object y) {} // name clash here 
} 

在這裏再次名稱衝突,因爲你必須有作爲一套參數任何類型的參數,你給X。在這裏,您將傳遞給x類型參數T,但是您將set方法的參數設置爲java.lang.Object。因此名稱衝突。

對於z工作,你必須有:

class z1<E> extends x<Object> { 
     void set(Object y) {} 
} 
+0

讓我們談談y類和z類。由於兩者都有類型參數不是類x中的類型參數的子類型,並且在刪除與類z具有相同方法簽名之後的類y中,我沒有看到類y和類z之間的區別。那麼爲什麼這個名字在類y上而不是在類z上發生衝突呢? - yapkm01 5分鐘前 – yapkm01

+0

看,因爲你重寫了方法集,所以它必須遵循一些規則。 y和z都有類型參數。這並不重要,因爲問題不在於此。該問題嚴格是由於set方法的參數類型。在x的set方法中,你有以下幾點: 'void set(T t){}'right? 現在每個嘗試重寫此set方法的子類都必須具有T類型或T類型超類的參數,以便它可以引用傳遞給它的類型爲T的對象。現在在類z中,參數是Object,它可以引用任何類型,也可以是T. – aps

+0

還有一件事:不要通過考慮擦除後發生的事情來混淆自己。擦除後會發生什麼並不重要。只是從強制的角度思考,泛型會變得更容易。 – aps