java中使用泛型处理程序处理事件
我编写了定制的dispathing/handling事件系统,通常如下所示: 事件处理程序接口: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); } 公共抽象类事件{
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没有对事件/委派的本机支持,这真是令人尴尬。所有现代语言都有。