[英]Events handling with generic handlers in java
我編寫了自定義干擾/處理事件系統,通常如下所示:
事件處理程序接口:
public interface EventHandler{
}
基本事件類:
public abstract class Event<H extends EventHandler> {
public static Class Type<H> { }
public abstract void dispatch(H handler);
}
處理程序經理:
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) {...}
...
}
而且一切都很好,但我想使用類似
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);
}
現在,當我向為字符串(例如,整數)生成事件的管理器注冊處理程序DataChangeHandler時,此注冊的處理程序將同時接收兩個事件,這會導致在我想讀取數據時發生ClassCastException。 我了解泛型沒有一些特殊的類,並且盡管在DataChangeHandler中定義了類型,但它們仍存儲在處理程序映射的同一列表中。
有什么辦法可以使其工作?
這似乎是一個非常非常臭的設計。 為什么要使用處理該事件類型的類來輸入事件? 那是倒退。 應使用其處理的事件類型鍵入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);
}
}
}
這種類型的設計將過濾掉處理程序無法處理的事件。
泛型在很大程度上是編譯時功能。 如果在運行時需要類型,則需要將類作為參數傳遞並將其存儲在字段中。
恕我直言:創建干擾點的一種更優雅的方法是使用注釋。 喜歡
@EventHandler
public void onMyEvent(MyEvent event) {
// is called when MyEvent is dispacted.
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.