Re: Generics
"kofa" <kovacs.it@gmail.com> wrote in message
news:1183114524.470649.204660@m36g2000hse.googlegroups.com...
Copying manually, casting individual elements solves that:
===
public <T extends Event> Set<EventListener<? super T>> get(Class<?
extends T> key) {
Set<EventListener<? super T>> listeners = new HashSet<EventListener<?
super T>>();
for (Entry<Class<? extends Event>, Set<EventListener<?>>> entry :
myListenersByType.entrySet()) {
listeners.add((EventListener<? super T>) entry.getValue());
}
return listeners;
}
===
Is there a nicer way?
Depends on your metric for "niceness". I haven't been able to fully
get rid of warnings. I can move the warning around to different locations
where they might make more sense. For example, you could have the
listeners provide a way to "cast themselves" to the proper type:
<code>
class EventImpl<T extends Event> implements EventListener<T> {
Class<? extends T> eventType;
@Override
public void eventRaised(T event) {
// TODO Auto-generated method stub
}
@Override
public <U extends Event> EventListener<? super U>
castSelfAsHandlerFor(Class<? extends U> clazz) {
if (eventType.isAssignableFrom(clazz)) {
return (EventListener<? super U>) this;
} else {
return null;
}
}
}
</code>
Or you could have the code in the event manager take advantage of the fact
that it just knows (but can't express this in the Java type system) that
Class<T> is mapped onto EventListener<T>:
<code>
@Override
public <T extends Event> void raiseEvent(T event) {
for (Class<? extends Event> key : myListenersByType.keySet()) {
if (key.isInstance(event)) {
Set<EventListener<? super T>> listeners = myListenersByType
.get((Class<? extends T>)key);
for (EventListener<? super T> listener : listeners) {
listener.eventRaised(event);
}
}
}
}
</code>
- Oliver