好吧,这解释起来很困惑。我会尽力的。
受到 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.equals(cl)
,它将 Event
的实例与 Class
的实例( Event
的实例) - 这永远不会返回 true。您想做的是:
if(e.getClass().equals(cl)) {
m.invoke(clss, e);
}
或者,如果您希望使用 @EventHandler
注解的方法来处理其方法签名定义的类的所有子类(即像 handle(Event e)
这样的方法将被 PlayerMoveEvents
以及所有其他事件调用),那么你想要:
if(cl.isAssignableFrom(e.getClass())) {
m.invoke(clss, e);
}
请参阅Class
Javadoc here了解更多信息。
请注意,我认为您的代码中还存在一些其他问题。例如,应使用包含用 @EventHandler
注解的方法的类实例来调用 Method.invoke
。您的代码有点不清楚,但我相信这应该是:
m.invoke(o, e);
此外,通过调用 o.getClass().getClasses()
,您正在迭代 o
类中定义的类 - 您可能想要迭代直接使用o
类的方法,即:
for (Method m : o.getClass().getMethods()) {
if (m.getAnnotation(EventHandler.class) != null) {
Class[] requiredTypes = m.getParameterTypes();
if (requiredTypes.length == 1 && requiredTypes[0].isAssignableFrom(e.getClass()) {
m.invoke(o, e);
}
}
}
关于java - 使用 Java 反射处理事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18471631/