好的,這很容易解釋。我會盡力。使用Java反射處理事件
受Bukkit事件系統的啓發,您只需使用@EventHandler就可以使事件處理程序變爲空白。
例子:
@EventHandler
public void aRandomName(PlayerMoveEvent ev) {
}
正如你所看到的,方法的名稱並不重要。傳遞的事件由事件參數類型確定。
所有事件都會擴展Event類。 我已經編寫了一些我認爲可行的代碼,除了一件事。
public List<Object> eventContainers;
public void fireEvent(Event e) {
Method[] methods;
for (Object o : eventContainers) {
Object[] classes = o.getClass().getClasses();
for (Object clss : classes) {
methods = clss.getClass().getMethods();
for (Method m : methods) {
if (m.getAnnotation(EventHandler.class) != null) {
try {
Class[] requiredTypes = m.getParameterTypes();
for(Class cl : requiredTypes) {
if(e.equals(cl)) {
m.invoke(clss, e);
}
}
} catch (IllegalAccessException ex) {
} catch (IllegalArgumentException ex) {
} catch (InvocationTargetException ex) {
}
}
}
}
}
}
什麼我的代碼呢: 循環遍歷eventContainers所有類,尋找那些具有@EventHandler註釋和指定的事件發送到該方法的方法。但是,我想查看fireEvent(Event e)中給定事件是什麼類型的事件,然後查看需要此類事件參數的方法。我會怎麼做?我想,
Class[] requiredTypes = m.getParameterTypes();
for(Class cl : requiredTypes) {
if(e.equals(cl)) {
m.invoke(clss, e);
}
}
將無法正常工作。
最終我希望能夠將事件傳遞給插件。就像這樣:
EventManager.fireEvent(new PlayerMoveEvent(player));
將被髮送到所有的插件,並有
@EventHandler
public void aVoid(PlayerMoveEvent e) {
//stuff
}
如果您有任何疑問插件,我會盡量解釋更好。在此先感謝您的幫助!
通過查看那段代碼,您似乎嘗試將事件e轉換爲方法中所需的參數。如果不能完成,那麼它將不會被髮送? (如異常捕捉)我認爲這是我正在尋找的。非常感謝! – Limnic
這就是我所做的,將事件轉換爲所需的參數。您可以使用普通的try/catch塊來進行異常處理。請參閱InvocationTargetException,IllegalAccessException和ClassCastException。 – 2013-08-27 17:36:15