You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用URLClassLoader加载类后调用构造函数触发IllegalAccessException

问题:为何无法访问已加载类的public构造函数?

尝试从文件系统(不在主程序类路径中)加载类并获取实例,代码如下:

try {
    File folder = new File("/tmp/");
    URLClassLoader loader = URLClassLoader.newInstance(new URL[] {folder.toURI().toURL()});
    Class clazz = loader.loadClass("testpkg.test");
    Constructor constructor = clazz.getConstructor();
    Object instance = constructor.newInstance();
} catch (Exception e) {
    e.printStackTrace();
}

被加载的类文件位于/tmp/testpkg/test.class,其源码为:

package testpkg;
class test{
    public test(){
            System.out.println("I am the constructor!");
    }
}

执行Object instance = constructor.newInstance();时触发运行时错误,错误信息:

java.lang.IllegalAccessException: Class tmp.ClassLoadingFun can not access a member of class testpkg.test with modifiers "public"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
at java.lang.reflect.Constructor.newInstance(Constructor.java:413)
at tmp.ClassLoadingFun.<init>(ClassLoadingFun.java:16)
at tmp.ClassLoadingFun.main(ClassLoadingFun.java:23)

修改包名或类名会提前触发找不到类的错误,说明类加载成功,但构造函数调用失败。

解答

问题出在类本身的访问权限上:你的test类没有添加public修饰符,默认是包级私有访问权限。即使构造函数是public,但类本身对外不可见,外部包的tmp.ClassLoadingFun无法直接访问这个类的成员,包括构造函数。

解决方法有两种:

  1. 修改test类的访问修饰符为public:
package testpkg;
public class test{ // 添加public修饰符
    public test(){
            System.out.println("I am the constructor!");
    }
}

重新编译后,外部就能正常通过反射创建实例。

  1. 通过反射强制开启构造函数的访问权限:
    在调用newInstance()之前,设置构造器的accessible属性为true,绕过访问检查:
Constructor constructor = clazz.getConstructor();
constructor.setAccessible(true); // 添加这一行
Object instance = constructor.newInstance();

内容的提问来源于stack exchange,提问作者roediGERhard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 14:01:12