2012-05-16 213 views
0

我不明白爲什麼編譯器不接受此代碼,Java泛型編譯錯誤

import javax.swing.event.EventListenerList; 

import java.util.EventListener; 


public class GenericEventsManager { 

    EventListenerList listeners = new EventListenerList(); 


    public <T extends EventListener> void addListener(T listener) { 
     listeners.add(listener.getClass(), listener); 
    } 
} 

我得到的錯誤是

The method add(Class<T>, T) in the type EventListenerList is not applicable for the arguments (Class<capture#1-of ? extends EventListener>, T) 

中的addListener的論點是,延伸的類型EventListener,所以listener.getClass()返回Class<? extends EventListener>,這正是EventListenerList.add方法所期望的。

有人可以解釋這一點嗎?我有一種感覺,它是與的getClass()未在編譯時解決,但它仍然沒有任何意義,我

回答

2

沒有通配符的通用參數不是變體,因此需要完全相同的類型(不是子類型,不是超類型)。 (source

編譯器根本不會讓你這樣做。如錯誤消息所示,Class參數上的類型參數必須爲,正好爲,與第二個參數的類型相同,在上面的代碼中不是這樣。


怎會不相同?

由於listener.getClass()返回類型爲Class<? extends EventListener>,不Class<T>。你可以 - 但我不建議這樣做 - 投返回Class,使這個編譯:

listeners.add((Class<T>)listener.getClass(), listener); 

你會得到一個編譯器警告這樣做時:

Type safety: Unchecked cast from Class<capture#1-of ? extends EventListener> to Class<T> 

,因爲這是不是一個(類型)安全演員。


這可能的根本原因(我真的不知道)是在EventListenerList#add()的聲明只是可憐的API設計。通常爲PECS is used in this kind of situation;這可能是因爲add()沒有通配。

+0

他們怎麼能不一樣? – Hilikus

+0

@Hilikus看到我的編輯。 –

+0

我明白了。爲什麼編譯器不能更進一步,弄清楚T **是**「?extends EventListener」? – Hilikus

0

是但在你的add方法您指定一個Class<T>,不是Class<EventListener>