java中使用泛型处理程序处理事件

java中使用泛型处理程序处理事件,java,events,generics,handler,Java,Events,Generics,Handler,我编写了定制的dispathing/handling事件系统,通常如下所示: 事件处理程序接口: public interface EventHandler{ } 基本事件类: public abstract class Event<H extends EventHandler> { public static Class Type<H> { } public abstract void dispatch(H handler); } 公共抽象类事件{

我编写了定制的dispathing/handling事件系统,通常如下所示:

事件处理程序接口:

public interface EventHandler{
}
基本事件类:

public abstract class Event<H extends EventHandler> {
    public static Class Type<H> { }
    public abstract void dispatch(H handler);
}
公共抽象类事件{
公共静态类类型{}
公开摘要无效分派(H处理程序);
}
处理程序经理:

public class HandlerManager {
    private Map<Event.Type, List<EventHandler>> map = new HashMap<Event.Type, List<EventHandler>>();
    public void register(Event.Type<H> type, H handler) {
        if(map.get(type) == null) { map.put(type, new ArrayList<EventHandler>()); }
        map.get(type).add(handler);
    }

    public void fire(Event<H> event) {...}
    ...
}
公共类HandlerManager{
私有映射映射=新的HashMap();
公共无效寄存器(Event.Type,H处理程序){
if(map.get(type)==null){map.put(type,new ArrayList());}
map.get(type).add(handler);
}
公共空间火灾(事件){…}
...
}
一切都很好,但我想使用类似的事件

public class DataChangeEvent<D> extends Event<DataChangeHandler<D>> {
    public static final Type<?> TYPE = new Type<?>();
    D data;
    ...
    public void dispatch(DataChangeHandler<D> handler) {
        handler.onDataChanged(this);
    }
    public D getData() { return data; }
}

public class DataChangeHandler<D> extends EventHandler {
    void onDataChanged(DataChangeEvent<D> event);
}
公共类DataChangeEvent扩展事件{
公共静态最终类型=新类型();
D数据;
...
公共无效调度(DataChangeHandler){
handler.onDataChanged(此);
}
public D getData(){return data;}
}
公共类DataChangeHandler扩展了EventHandler{
无效onDataChanged(DataChangeEvent事件);
}
现在,当我将处理程序DataChangeHandler注册到为字符串(例如整数)生成事件的管理器中时,这个注册的处理程序将接收两个事件,这两个事件都会导致我在读取数据时发生ClassCastException。 我知道泛型没有特殊的类,尽管DataChangeHandler中定义了类型,但它们存储在handlers映射的同一列表中


有什么办法可以让它工作吗?

这似乎是一个非常非常难闻的设计。为什么要用处理该类型事件的类来类型化事件?这是倒退。EventHandler的类型应与其处理的事件类型相同

所以我并没有完全明白你实际上想做什么,但我认为你基本上是在尝试这样做:

private Map<Class<?>, List<EventHandler>> map;
public <T> void register(Class<? extends T> typeFilter, EventHandler<T> handler) {
    map.get(typeFilter).add(handler);
}


//...later
//safe since we used a generic method to add 
@SuppressWarnings("unchecked"); 
public void fire(Event<?> event) {
    for ( EventHandler handler : map.get(event.getClass()) ) {
        handler.onDataChanged(event);
    }
}

//or similarly:
@SuppressWarnings("unchecked"); 
public void fire(Event<?> event) {
    for ( Class<?> type : map.keySet() ) {
        if ( !type.instanceOf(event) ) continue;
        for ( EventHandler handler : map.get(type) ) {
            handler.onDataChanged(event);
        }
    }
}

私有映射泛型在很大程度上是一种编译时特性。如果在运行时需要该类型,则需要将该类作为参数传递,并将其存储在字段中

IMHO:创建disacter的一种更简单的方法是使用注释。像

@EventHandler
public void onMyEvent(MyEvent event) {
   // is called when MyEvent is dispacted.
}

H在HandleManager中是从哪里来的?谢谢你把它放在一起!事实上,Java没有对事件/委派的本机支持,这真是令人尴尬。所有现代语言都有。