关于使用反射的IllegalAccessException [英] IllegalAccessException on using reflection

查看:205
本文介绍了关于使用反射的IllegalAccessException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图学习反射,但我遇到了这个IllegalAccessException。请参阅以下代码:

I was trying to learn reflection and I came across this IllegalAccessException. Please see the following code:

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));
      }
} 

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

When I tried to run this program, I got the following:

Exception in thread "main" IllegalAccessException

我不明白发生了什么。有任何想法吗?在此先感谢。

I don't understand what's going on. Any ideas? Thanks in advance.

推荐答案

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

You need to suppress Java language access checking in order to reflectively invoke a private method in another class, with setAccessible(true):

Method mtd= itr.getClass().getMethod("hasNext");
  if(!mtd.isAccessible()) {
      mtd.setAccessible(true);
 }

此外,当启用SecurityManager时,我们需要额外的权限来调用setAccessible(真正)。否则,我们得到:

Furthermore, when a SecurityManager is enable, we need extra permissions to call setAccessible(true). Otherwise, we get:

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:

We only want to grant this suppressAccessChecks permission to trusted code source, definitely not to all classes in the call stack. So we would modify 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;
         }
     });
 }
 }

这篇关于关于使用反射的IllegalAccessException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆