I am writing an event system for my Java application and I keep getting confused about generics.
Let's say this is EventManager.java
:
public class EventManager {
private final Map<Class<? extends Event>, List<EventHandler<?>>> eventHandlerMap = new HashMap<>();
public synchronized <T extends Event> void fire(T event) {
Class<? extends Event> eventClass = event.getClass();
if (!eventHandlerMap.containsKey(eventClass)) return;
List<EventHandler<? extends Event>> handlerList =
eventHandlerMap.get(eventClass);
for (EventHandler<? extends Event> eventHandler : handlerList) {
eventHandler.handleEvent(event.getClass().cast(event));
}
}
}
Event.java
:
public abstract class Event {
}
and EventHandler.java
:
public abstract class EventHandler<T extends Event> {
public abstract void handleEvent(T event);
}
IntelliJ IDEA reports me the following error:
As a temporary mitigation I have added the following method to EventHandler
class:
@SuppressWarnings("unchecked")
public final void handleEvent0(Event event) {
handleEvent((T) event);
}
...and changed the fire
method in EventManager
:
public synchronized void fire(Event event) {
Class<? extends Event> eventClass = event.getClass();
if (!eventHandlerMap.containsKey(eventClass)) return;
List<EventHandler<? extends Event>> handlerList =
eventHandlerMap.get(eventClass);
for (EventHandler<? extends Event> eventHandler : handlerList) {
eventHandler.handleEvent0(event);
}
}
This does work however I am wondering what I have done wrong initially and how can I properly fix it. Please help and sorry for my English!