그래, 이건 설명하기가 상당히 어렵습니다. 난 내 최선을 다할 것입니다.Java Reflection을 사용한 이벤트 처리
@ EventHandler를 사용하여 이벤트 핸들러를 void 처리 할 수있는 Bukkit Event System에서 영감을 얻었습니다.
예 :
@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);
}
}
는 작용하지 않을 것이다.
궁극적으로 저는 플러그인에 이벤트를 전달할 수 있기를 바랍니다. 이처럼 모든 플러그인과 당신은 질문이있는 경우
@EventHandler
public void aVoid(PlayerMoveEvent e) {
//stuff
}
이 플러그인로 전송됩니다
EventManager.fireEvent(new PlayerMoveEvent(player));
, 나는 더 나은 설명하려고합니다. 도와 주셔서 미리 감사드립니다.
코드 조각을 보면 이벤트 e를 메소드에 필요한 매개 변수로 캐스팅하려고 시도하는 것처럼 보입니다. 그것이 할 수없는 경우에 보내지 않을 것인가? (예외적으로 잡기) 나는 이것이 내가 찾고있는 것이라고 생각한다. 고마워! – Limnic
그것이 내가하는 일이며, 필요한 매개 변수로 이벤트를 캐스팅하십시오. 예외 처리를 위해 일반 try/catch 블록을 사용할 수 있습니다. InvocationTargetException, IllegalAccessException, ClassCastException을 참조하십시오. –