Oracle JavaDocs解释说IllegalAccessError是
“如果应用程序尝试访问或修改字段,则抛出 调用一个它无权访问的方法。“
我尝试动态加载一个类,我得到了这个异常。
如果我在使用类加载器动态加载具有私有包的类时正确理解IllegalAccessError
我正在尝试加载的类正在使用
org.xml.sax.helpers.SecuritySupport
不幸的是,我们无法使用反射加载类 *因为该类是包私有的。而且班上有 *为私有包,因此API不会暴露给其他人 *可以使用它们来规避安全性的代码。从而, *我们接受直接引用可能失败的风险 *在一些JDK 1.1 JVM上,即使我们永远不会执行 *在这种情况下这个代码。叹息...
我怎样才能动态加载它?我必须得到它的工作。 如果我在使用类加载器时遇到错误,我也无法从中恢复,所以我怎么能提前知道我无法加载这个类呢?
提前感谢任何帮助
的人答案 0 :(得分:2)
语句“我们无法使用反射加载类,因为类是包私有”没有任何意义,因为可以很容易地显示:
package somepackage;
class BaseClass {
public static void main(String[] args) throws ReflectiveOperationException {
BaseClass obj=(BaseClass)
Class.forName("somepackage.SubClass").newInstance();
obj.aMethod();
}
void aMethod() {
System.out.println("base class");
}
}
class SubClass extends BaseClass {
@Override
void aMethod() {
System.out.println("method overridden by subclass");
}
}
这完美无缺,打印method overridden by subclass
复制了SecuritySupport
类的实际用例。
但是,由于该类显然是为了允许Java 1.1和Java 1.2之间的转换,所以二十年前,当这种转换发生时,可能存在这样的限制。
但是,您的用例完全不同。你说你正在尝试加载一个“正在使用org.xml.sax.helpers.SecuritySupport
”的类,这并不意味着它正在通过Reflection使用所述类,但如上所示,无论如何都无关紧要。无论是哪种情况,它都可以工作,如果类在同一个包中,是否“动态”加载类。
只有两种可能的情况。
如果该类真正位于同一个包中,那么在运行时它意味着它也已被同一个类加载器加载,这也需要它也是JRE的一部分,如果JRE的{{1} } package定义了一个org.xml.sax.helpers
类,然后类可以访问同一个包中的类。
如果您尝试通过不同的SecuritySupport
从不同的代码源加载一个类,它将不属于该包,即使您为其提供了{{{ 1}}形式。如果JRE的ClassLoader
包恰好定义了org.xml.sax.helpers.SomeClass
类,则所有非JRE类都将位于不同的包中。当它试图访问那个不属于官方API的类时,它不起作用。
请注意,所有标准类加载器都遵循委托模型,首先尝试通过其父类加载器解析名称,这就是为什么他们都希望JRE的org.xml.sax.helpers
类(如果有)的原因。对于非标准类加载器,您可以使用具有该限定名称的不同的,不相关的类,位于不同的运行时包中。
在第二种情况下,问题出现了,为什么你的班级正在使用该类。在2017年,很少需要区分Java 1.1和Java 1.2,并且该类提供的功能也仅与JRE的特权代码源(或其他代码源)中的类相关。一般来说不同的特权。)