2014-04-09 47 views
1

我目前正在嘗試使用通用偵聽器來編寫事件系統。
應將所有偵聽器添加到單個EventSource對象,該對象將調用其特定事件的receiveEvent()方法。
Java泛型編譯器錯誤:出了什麼問題?

的EventSource

public class EventSource { 

private HashMap<String, List<EventListener<? extends Event>>> events = new HashMap<>(); 

public synchronized <T extends Event> void fireEvent(T event){ 
    String key = event.getClass().getName(); 
    if(events.containsKey(key)){ 
     Iterator<EventListener<? extends Event>> i = events.get(key).iterator(); 
     while(i.hasNext()){ 
      i.next().receiveEvent(event); //Compiler Error 
     } 
    } 
} 

產生的錯誤是:

The method receiveEvent(capture#2-of ? extends Event) in the type EventListener is not applicable for the arguments (T)

事件監聽只有:

public interface EventListener<T extends Event> { 
    public void receiveEvent(T event); 
} 

有人能解釋我是什麼DOI恩,錯了,拜託?

回答

1

的問題是,你遍歷一個List<EventListener<? extends Event>>,但是編譯器不知道哪個階級,EventEvent亞類中,?通配符可能。 T類型參數也可以是EventEvent的任何子類。他們不符合這個原因。

嘗試刪除通配符:

// Removed wildcard 
private HashMap<String, List<EventListener<Event>>> events = new HashMap<>(); 

public synchronized <T extends Event> void fireEvent(T event){ 
    String key = event.getClass().getName(); 
    if(events.containsKey(key)){ 
    // Removed wildcard. 
    Iterator<EventListener<Event>> i = events.get(key).iterator(); 
    while(i.hasNext()){ 
     i.next().receiveEvent(event); // This compiles now. 
    } 
    } 
} 
+0

謝謝了很多的作品。但我仍然沒有真正明白爲什麼這不起作用。當我初始化類'Class <的字段?用類型爲'Class >的對象擴展Event>'實際上有什麼作用,會不會有相同的錯誤? – 093r

+0

想象2個'Event'子類,'Event1'和'Event2'。理論上的'T'實際上可以是'Event1','?'可以是'Event2',在這種情況下它們是不兼容的。編譯器使用泛型的工作是確保類型安全性,並且由於這種可能性,它必須不允許傳遞可能是該方法不兼容的參數。 – rgettman

+0

好吧,我想我有點得到它。非常感謝! – 093r