2014-04-09 45 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