带有Map< Class&lt ;?的EventSource extends Event&gt ;, List< EventListener&lt ;?扩展事件>>没有未经检查的呼叫 [英] EventSource with Map<Class<? extends Event>, List<EventListener<? extends Event>> without unchecked call

查看:154
本文介绍了带有Map< Class&lt ;?的EventSource extends Event&gt ;, List< EventListener&lt ;?扩展事件>>没有未经检查的呼叫的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我有:

我需要实现观察者模式和每个事件类的监听器列表。空界面事件

  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&lt; Class&lt ;?的EventSource extends Event&gt ;, List&lt; EventListener&lt ;?扩展事件&gt;&gt;没有未经检查的呼叫的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆