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

问题描述



我有:

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

  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;没有未经检查的呼叫的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 01:35