带有Map< Class< ;?的EventSource extends Event> ;, List< EventListener< ;?扩展事件>>没有未经检查的呼叫 [英] EventSource with Map<Class<? extends Event>, List<EventListener<? extends Event>> without unchecked call
问题描述
我有:
我需要实现观察者模式和每个事件类的监听器列表。空界面事件
public interface Event {}
接口用于监听器:
public interface EventListener< T extends Event> {
void handle(T event);
Class< T> getEventClass();}
和事件来源:
public class EventSource {
private final Map&
public< T> void subscribe(EventListener< ;? extends Event> listener){
Class< ;?扩展事件> 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(事件); //< - 作为原始类型成员的'处理(T)'未经检查的调用...
}
}}
它可以工作,但我有未检查呼叫警告。
我试过了: (Event event){
for(EventListener< ;? extends Event> listener:listeners.get(event.getClass())){
listener.handle(event); //< - 编译错误
$ b
但在这种情况下,我有句柄无法应用to ...编译错误。
在此先感谢!
未经检查的调用警告报告有一个很好的原因 - 您使用了 EventListener
的原始形式。当你给一个类型参数?扩展事件
,它给编译错误,因为编译器不是哪个事件
EventListener
句柄 - 它只知道它是特定类型的事件
。同样,它不知道事件
的运行时类型 - 它可以是任何特定类型的 Event
。 p>
必须知道该类型的意义。我会制作 EventSource
泛型,指定具有有界泛型类型参数的 Event
类型。
class EventSource< E extends Event> {
许多?扩展事件
声明将改为使用 E
,例如
私人最终地图< Class< extends Event>,List< EventListener< E>>> listeners = new HashMap<>();
还有许多其他声明会改为使用 E
$ b
现在, fire
将会带一个 E
,以便它可以传递给句柄
:
public void fire(E event){
for(EventListener< E> listener:listeners.get(event.getClass())){
listener.handle(event); //现在编译
}
}
I need to implement Observer pattern with List of listeners per Event class.
I have:
empty interface Event
public interface Event {}
interface for Listeners:
public interface EventListener<T extends Event> {
void handle(T event);
Class<T> getEventClass();}
and event source:
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...
}
}}
It works, but I have "Unchecked call" warning. How to avoid it?
I tried:
public void fire(Event event) {
for (EventListener<? extends Event> listener : listeners.get(event.getClass())) {
listener.handle(event);//<-- compilation error
}
}
but in this case I have "handle cannot be applied to..." compilation error.
Thanks in advance!
The "unchecked call" warning was reported for a good reason - you used the raw form of EventListener
. When you gave a type parameter ? extends Event
, it gave the compilation error because the compiler doesn't which Event
the EventListener
handles - it only knows that it is a specific type of Event
. Likewise, it doesn't know the runtime type of event
- it could be any specific type of Event
.
The type must be known for this to make sense. I would make EventSource
generic, specifying the type of Event
with a bounded generic type parameter.
class EventSource<E extends Event> {
Many ? extends Event
declarations will change to use E
, e.g.
private final Map<Class<? extends Event>, List<EventListener<E>>> listeners = new HashMap<>();
There are many other declarations that will change to use E
.
Now, fire
will take an E
so that it can be passed to handle
:
public void fire(E event) {
for (EventListener<E> listener : listeners.get(event.getClass())) {
listener.handle(event); // Now this compiles
}
}
这篇关于带有Map< Class< ;?的EventSource extends Event> ;, List< EventListener< ;?扩展事件>>没有未经检查的呼叫的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!