首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于使用反射的IllegalAccessException

关于使用反射的IllegalAccessException
EN

Stack Overflow用户
提问于 2011-03-04 01:33:57
回答 5查看 43.4K关注 0票数 15

我正在尝试学习反射,我偶然发现了这个IllegalAccessException。请参考以下代码:

代码语言:javascript
复制
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));
      }
} 

当我尝试运行这个程序时,我得到了以下信息:

代码语言:javascript
复制
Exception in thread "main" IllegalAccessException

我不明白这是怎么回事。有什么想法吗?提前谢谢。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-03-04 01:38:30

您需要抑制Java语言访问检查,以便反射地调用另一个类中的私有方法,并使用setAccessible(true):

代码语言:javascript
复制
Method mtd= itr.getClass().getMethod("hasNext");
  if(!mtd.isAccessible()) {
      mtd.setAccessible(true);
 }

此外,当启用SecurityManager时,我们需要额外的权限才能调用setAccessible(true)。否则,我们会得到:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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;
         }
     });
 }
 }
票数 37
EN

Stack Overflow用户

发布于 2011-03-04 01:48:57

最麻烦的代码是:

代码语言:javascript
复制
itr.getClass().getMethod

您可能需要在Iterator类上使用hasNext。您已经编写的是HashMap.KeyIterator类,根据Java语言访问说明符(或者至少是反射所使用的JDK1.0的粗略解释),它对您的代码不可用。

请改用:

代码语言:javascript
复制
Iterator.class.getMethod

(如果不是为了学习的目的,那就远离反思。)

票数 8
EN

Stack Overflow用户

发布于 2011-03-04 01:48:12

您不能访问它,因为Iterator是一个私有内部类。更多的解释可以在here找到。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5184284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档