Java 带有映射的EventSource<;类别<;?扩展事件>;,列表<;EventListener<;?扩展事件>&燃气轮机;没有未经检查的呼叫
我需要使用每个事件类的侦听器列表来实现观察者模式 我有: 空接口事件Java 带有映射的EventSource<;类别<;?扩展事件>;,列表<;EventListener<;?扩展事件>&燃气轮机;没有未经检查的呼叫,java,generics,observer-pattern,unchecked,Java,Generics,Observer Pattern,Unchecked,我需要使用每个事件类的侦听器列表来实现观察者模式 我有: 空接口事件 public interface Event {} 侦听器接口: public interface EventListener<T extends Event> { void handle(T event); Class<T> getEventClass();} 公共接口事件监听器{ 无效句柄(T事件); 类getEventClass();} 和事件来源: public class EventS
public interface Event {}
侦听器接口:
public interface EventListener<T extends Event> {
void handle(T event);
Class<T> getEventClass();}
公共接口事件监听器{
无效句柄(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...
}
}}
公共类事件源{
私人最终地图改变
listeners.put(eventClass,newarraylist());
到
listeners.put(eventClass,newarraylist未检查的调用)报告警告是有充分理由的-您使用了原始形式的EventListener
。当您提供类型参数?extensed Event
,它给出了编译错误,因为编译器不知道Event
由EventListener
处理哪个Event
类型-它只知道它是Event
的特定类型kewise,它不知道事件的运行时类型
——它可以是任何特定类型的事件
必须知道类型才能使其有意义。我将使EventSource
成为泛型,使用有界泛型类型参数指定Event
的类型
class EventSource<E extends Event> {
还有许多其他声明将更改为使用E
现在,fire
将接受一个E
,以便它可以被传递到句柄
:
public void fire(E event) {
for (EventListener<E> listener : listeners.get(event.getClass())) {
listener.handle(event); // Now this compiles
}
}
公共空间火灾(E事件){
for(EventListener:listeners.get(event.getClass())){
handle(event);//现在编译
}
}
使用NetBeans 7.4我不知道您的错误,但我确实知道:不兼容类型:ArrayList无法转换为ListThank谢谢您的建议。我理解这个问题。在MapThank中,我不能简单地更改Thank,但它不会更改任何内容。在Java 7(diamond)中是自动替代吗EventListener@VitalyChibrikov我使用的是Java 7,并且没有在LHS运算符上定义菱形运算符,因为您只是使用put
调用创建ArrayList。因此,必须显式设置它,否则编译器只会推断是的,您是对的。listeners.put(eventClass,new ArrayList());是1.8项目级别,而不是1.7。正如您所提到的,在Java 7中,我需要通用初始化的完整版本。
listeners.put(eventClass, new ArrayList<EventListener<? extends Event>>());
class EventSource<E extends Event> {
private final Map<Class<? extends Event>, List<EventListener<E>>> listeners = new HashMap<>();
public void fire(E event) {
for (EventListener<E> listener : listeners.get(event.getClass())) {
listener.handle(event); // Now this compiles
}
}