The problem is that the type of the value of the map is the wildcarded type Collection<EventHandler<? extends Event>>. To this type you can cast. When you write your method, it returns a concrete type, the T which is contracted by the parameter. But java cannot determine if the value fetched by the key-value Class<T> would have the appropriate type. There exists no correlation between the key and the value. If you use wildcards and you want retrieve concrete types from any wildcarded type you must always cast. The bounded wildcard is for writing a common contract like an abstract class or an interface.
Look also at
this and
this and
this.
A way to implement your relationship would be a structure like this:
class Example<E extends Event> {
private Class<E> clazz;
private Collection<EventHandler<E>> collection;
}
Also you can first use an upper common type and then make a cast to concrete type:
static <T extends Event, E extends T> Collection<EventHandler<T>> getHandlers(Class<T> eventType) {
Collection<?> col = EVENT_HANDLERS.get(eventType);
return (Collection<EventHandler<T>>)col;
}
Actual it's not a solution for your problem