我试图在Java中使用Reflection但我得到一个奇怪的错误.当我收到错误消息时会出现以下问题:
java.lang.IllegalAccessException: Class com.myapp.core.utils.EventDispatcher can not access a member of class appApp$1 with modifiers "public"
at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
Run Code Online (Sandbox Code Playgroud)
我只是尝试创建自己的EventDispatcher类,在其中,我使用反射的部分,这也是导致问题的代码行:
public void dispatchEvent(Event e, String callMethName) {
IEventListener list = ((IEventListener)listeners[i]);
list.getClass().getMethod(callMethName, Event.class).invoke(list, e);
}
Run Code Online (Sandbox Code Playgroud)
在我的主类上,我有一些调用addListener的东西,它只是通过这种方式将监听器添加到EventDispatcher类的列表中:
try {
obj.addListener("onTestHandler", new MyTestEventListener(){
@Override
public void onTestHandler(Event e) {
System.out.println("hello!");
}
});
} catch (SecurityException e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
因此,第一个表示"onTestHandler"的参数将传递给EventDispatcher类,并最终作为dispatchEvent方法中参数callMethName的一部分,该方法将动态调用该方法.
方法的传递和一切都是正确的.它是反射某种方式存在问题的部分.它似乎能够找到方法.但由于某种原因,抛出IllegalAccessException并且无法调用该方法.
为什么会这样?
谢谢.
McD*_*ell 18
我怀疑实现的匿名类(appApp$1)MyTestEventListener具有包可见性,反射代码在另一个包中.
对于此代码:
package foo.p1;
public class Target {
public static interface Foo {
public void bar();
}
public static Foo newFoo() {
return new Foo() {
@Override
public void bar() {
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
此代码将失败,因为返回的运行时类型newFoo()不是公共类:
package foo.p2;
import foo.p1.Target;
public class Main {
public static void main(String[] args) throws Exception {
Target.Foo foo = Target.newFoo();
foo.getClass()
.getMethod("bar")
.invoke(foo);
}
}
Run Code Online (Sandbox Code Playgroud)
这可以通过将方法设置为可访问来克服:
Target.Foo foo = Target.newFoo();
Method m = foo.getClass()
.getMethod("bar");
m.setAccessible(true);
m.invoke(foo);
Run Code Online (Sandbox Code Playgroud)
或者通过使用公共接口中的方法:
Target.Foo foo = Target.newFoo();
Target.Foo.class.getMethod("bar")
.invoke(foo);
Run Code Online (Sandbox Code Playgroud)