EventSource with Map<Class<? extends Event>, List<EventListener<? extends Event>> 没有未经检查的调用
EventSource with Map<Class<? extends Event>, List<EventListener<? extends Event>> without unchecked call
我需要使用每个事件的侦听器列表来实现观察者模式 class。
我有:
空接口事件
public interface Event {}
听众界面:
public interface EventListener<T extends Event> {
void handle(T event);
Class<T> getEventClass();}
事件来源:
public class EventSource {
private final Map<Class<? extends Event>, List<EventListener<? extends Event>>> listeners = new HashMap<>();
public <T> void subscribe(EventListener<? extends Event> listener) {
Class<? extends Event> eventClass = listener.getEventClass();
if (!listeners.containsKey(eventClass)) {
listeners.put(eventClass, new ArrayList<>());
}
listeners.get(eventClass).add(listener);
}
public void unsubscribe(EventListener listener) {
listeners.remove(listener.getEventClass());
}
public void fire(Event event) {
for (EventListener listener : listeners.get(event.getClass())) {
listener.handle(event); //<-- Unchecked call to 'handle(T)' as a member of raw type...
}
}}
有效,但我有 "Unchecked call" 警告。如何避免?
我试过:
public void fire(Event event) {
for (EventListener<? extends Event> listener : listeners.get(event.getClass())) {
listener.handle(event);//<-- compilation error
}
}
但在这种情况下我有 "handle cannot be applied to..." 编译错误。
提前致谢!
改变
listeners.put(eventClass, new ArrayList<>());
至
listeners.put(eventClass, new ArrayList<EventListener<? extends Event>>());
我相信这将使接口方法 handle
表现得像预期的那样
报告 "unchecked call" 警告是有充分理由的 - 您使用了 EventListener
的原始形式。当你给出一个类型参数 ? extends Event
时,它给出了编译错误,因为编译器没有 Event
EventListener
处理它 - 它只知道它是 [=15 的特定类型=].同样,它不知道 event
的运行时类型 - 它可以是 Event
.
的任何特定类型
必须知道类型才有意义。我会让 EventSource
泛型,用有界泛型类型参数指定 Event
的类型。
class EventSource<E extends Event> {
许多 ? extends Event
声明将更改为使用 E
,例如
private final Map<Class<? extends Event>, List<EventListener<E>>> listeners = new HashMap<>();
还有许多其他声明将更改为使用 E
。
现在,fire
将接受一个 E
,以便它可以传递给 handle
:
public void fire(E event) {
for (EventListener<E> listener : listeners.get(event.getClass())) {
listener.handle(event); // Now this compiles
}
}
我需要使用每个事件的侦听器列表来实现观察者模式 class。
我有:
空接口事件
public interface Event {}
听众界面:
public interface EventListener<T extends Event> {
void handle(T event);
Class<T> getEventClass();}
事件来源:
public class EventSource {
private final Map<Class<? extends Event>, List<EventListener<? extends Event>>> listeners = new HashMap<>();
public <T> void subscribe(EventListener<? extends Event> listener) {
Class<? extends Event> eventClass = listener.getEventClass();
if (!listeners.containsKey(eventClass)) {
listeners.put(eventClass, new ArrayList<>());
}
listeners.get(eventClass).add(listener);
}
public void unsubscribe(EventListener listener) {
listeners.remove(listener.getEventClass());
}
public void fire(Event event) {
for (EventListener listener : listeners.get(event.getClass())) {
listener.handle(event); //<-- Unchecked call to 'handle(T)' as a member of raw type...
}
}}
有效,但我有 "Unchecked call" 警告。如何避免?
我试过:
public void fire(Event event) {
for (EventListener<? extends Event> listener : listeners.get(event.getClass())) {
listener.handle(event);//<-- compilation error
}
}
但在这种情况下我有 "handle cannot be applied to..." 编译错误。
提前致谢!
改变
listeners.put(eventClass, new ArrayList<>());
至
listeners.put(eventClass, new ArrayList<EventListener<? extends Event>>());
我相信这将使接口方法 handle
表现得像预期的那样
报告 "unchecked call" 警告是有充分理由的 - 您使用了 EventListener
的原始形式。当你给出一个类型参数 ? extends Event
时,它给出了编译错误,因为编译器没有 Event
EventListener
处理它 - 它只知道它是 [=15 的特定类型=].同样,它不知道 event
的运行时类型 - 它可以是 Event
.
必须知道类型才有意义。我会让 EventSource
泛型,用有界泛型类型参数指定 Event
的类型。
class EventSource<E extends Event> {
许多 ? extends Event
声明将更改为使用 E
,例如
private final Map<Class<? extends Event>, List<EventListener<E>>> listeners = new HashMap<>();
还有许多其他声明将更改为使用 E
。
现在,fire
将接受一个 E
,以便它可以传递给 handle
:
public void fire(E event) {
for (EventListener<E> listener : listeners.get(event.getClass())) {
listener.handle(event); // Now this compiles
}
}