我正在尝试学习反射,我偶然发现了这个IllegalAccessException。请参考以下代码:
public class ReflectionTest
{
public static void main(String[] args)
{
Set<String> myStr = new HashSet<String>();
myStr.add("obj1");
Iterator itr = myStr.iterator();
Method mtd = itr.getClass().getMethod("hasNext");
System.out.println(m.invoke(it));
}
} 当我尝试运行这个程序时,我得到了以下信息:
Exception in thread "main" IllegalAccessException我不明白这是怎么回事。有什么想法吗?提前谢谢。
发布于 2011-03-04 01:38:30
您需要抑制Java语言访问检查,以便反射地调用另一个类中的私有方法,并使用setAccessible(true):
Method mtd= itr.getClass().getMethod("hasNext");
if(!mtd.isAccessible()) {
mtd.setAccessible(true);
}此外,当启用SecurityManager时,我们需要额外的权限才能调用setAccessible(true)。否则,我们会得到:
C:\ReflectionTest>java -Djava.security.manager CallFoo
Exception in thread "main" java.security.AccessControlException: access denied (java.lang.reflect.ReflectPermission suppressAccessChecks)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
at java.security.AccessController.checkPermission(AccessController.java:427)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:107)
at CallFoo.main(CallFoo.java:8)我们只想将此suppressAccessChecks权限授予受信任的代码源,而不是调用堆栈中的所有类。因此,我们将修改CallFoo.java:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
public class CallFoo {
public static void main(String args[]) throws Exception {
doCallFoo();
}
public static void doCallFoo() throws IllegalAccessException, ClassNotFoundException, NoSuchMethodException,
InvocationTargetException, InstantiationException, PrivilegedActionException {
Class fooClass = Class.forName("Foo");
final Foo foo = (Foo) fooClass.newInstance();
final Method helloMethod = fooClass.getDeclaredMethod("hello");
AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws Exception {
if(!helloMethod.isAccessible()) {
helloMethod.setAccessible(true);
}
helloMethod.invoke(foo);
return null;
}
});
}
}发布于 2011-03-04 01:48:57
最麻烦的代码是:
itr.getClass().getMethod您可能需要在Iterator类上使用hasNext。您已经编写的是HashMap.KeyIterator类,根据Java语言访问说明符(或者至少是反射所使用的JDK1.0的粗略解释),它对您的代码不可用。
请改用:
Iterator.class.getMethod(如果不是为了学习的目的,那就远离反思。)
发布于 2011-03-04 01:48:12
您不能访问它,因为Iterator是一个私有内部类。更多的解释可以在here找到。
https://stackoverflow.com/questions/5184284
复制相似问题