Question

I am currently trying to program an event system using generic Listeners.
All listeners should be added to a single EventSource Object which will call their receiveEvent() methods for a specific event.

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 resulting error is:

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

EventListener is only:

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

Could someone explain what I am doing wrong, please?

Was it helpful?

Solution

The problem is that you're iterating over a List<EventListener<? extends Event>>, but the compiler doesn't know which class, Event or a subclass of Event, the ? wildcard could be. The T type parameter could also be Event or any subclass of Event. They do not match for this reason.

Try removing the wildcards:

// 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.
     }
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top