当前位置: 首页 > 面试题库 >

使用反射时出现IllegalAccessException

计和顺
2023-03-14
问题内容

我试图学习反思,并且遇到了这个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

我不明白发生了什么。有任何想法吗?提前致谢。


问题答案:

您需要禁止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)

我们只想向可信任的代码源(而不是对调用堆栈中的所有类)授予该excludeAccessChecks权限。因此,我们将修改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;
         }
     });
 }
 }


 类似资料:
  • 我有一个奇怪的错误:我有一个使用Hibernate的注释类。一切都很好,直到我开始这样介绍日志: 产生的错误是: [错误]原因:org。冬眠MappingException:无法确定组织的类型。slf4j。Logger,位于table:container,用于列:[org.hibernate.mapping.Column(Logger)] 根据我的理解,在这种情况下,静态场应该是合适的。那么为什么

  • 问题内容: 前几天,我通过手动将类的每个元素写成String来为Java中的类编写toString(),我想到使用反射可能可以创建一个通用的toString()方法在所有课程上。IE浏览器将找出字段名称和值,并将其发送到字符串。 获取字段名称非常简单,这是同事提出的: 使用工厂,我可以通过在第一次调用toString()时存储一次字段来减少性能开销。但是,找到这些值可能会贵得多。 由于反射的作用,

  • 问题内容: Avro序列化在Hadoop用户中很流行,但是很难找到示例。 谁能帮我这个示例代码?我对使用Reflect API读取/写入文件以及使用Union和Null注释最感兴趣。 问题答案: 这是上述程序的有效版本。 这也对文件使用压缩。

  • 我的代码很简单,就像 我如何验证Scala的映射以检查它是否为空?

  • 我想动态调用jsoup中的一个方法。这里是我的用例,我实际上在jsoup中调用多个select dom方法来遍历内部, 我能实现同样的动态像, 我知道我们可以使用反射来实现,但不确定如何实现这种行为,因为模式字符串将是动态的,并且可能有n个dom选择器。 让我知道如果上面的动力是可能的。

  • 我试图创建一个方法,它接受两个字符串参数,并对对象调用一个方法调用。这两个参数将提供className和methodName。理想情况下,我希望使用反射找到对象和方法,然后调用该方法。这是我管理的一个自动化套件。 当我运行它时,我收到一个错误nosuchMethodException:java.lang.String.isPageDisplayed()。 我相信我的问题存在于寻找对象或与对象有关的