必须用getDeclaredConstructor()获取私有构造器并调用setAccessible(true)才能创建实例;否则抛NoSuchMethodException或IllegalAccessException,Java 9+模块限制下还可能触发InaccessibleObjectException。
Java 反射调用私有构造器:
是唯一入口
想绕过访问控制创建私有构造的对象,必须用
,而不是
—— 后者只查 public 构造器,私有的直接抛
。
关键点在于「declared」这个词:它表示本类声明的所有构造器,不管访问修饰符。但默认仍受 Java 访问检查限制,所以紧接着必须调用
才能真正调用。
查不到私有构造器,别白试
要传入精确参数类型,比如
,不能传实例值
如果构造器带泛型参数(如
),运行时已擦除,按原始类型写,即
多个重载私有构造器时,参数类型不匹配会抛
,不是
调用前必须
,否则
逃不掉
即使拿到了
对象,不设为可访问就 newInstance,JVM 会在运行时拦截并抛出
。这不是异常处理能绕过的逻辑检查,是 SecurityManager(或模块系统)的硬性闸门。
注意:从 Java 9 开始,模块系统默认禁止对非开放包的反射访问,即使
也可能失败,报
—— 这时候得加 JVM 参数
或改模块配置。
立即学习
“
Java免费学习笔记(深入)
”;
Eclipse导入Android或其他的JAVA项目的正确方法 WORD版
本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
下载
必须在
前调用,顺序错等于没开锁
该调用本身可能抛
(如有安全管理器且策略拒绝)
Java 12+ 在某些安全敏感上下文中(如某些容器、Android ART)会静默忽略
,实际仍不可访问
常见误用场景:反序列化、Mock 框架、单元测试中的陷阱
很多框架(如 Mockito、Jackson 默认反序列化器)内部也靠反射调私有构造器,但它们都做了容错封装。你自己手写时容易漏掉边界条件。
比如:构造器抛异常、含 final 字段未初始化、依赖外部状态(如静态字段未 setup)、或对象创建后未触发必要的初始化逻辑(如
方法不会自动执行)。
构造器抛
会原样抛出,不是包装成
—— 注意捕获类型
若类含
字段且依赖构造器外赋值(如静态块),反射创建对象时这些字段仍是默认值(
/
)
Spring 的
字段不会自动注入,反射创建的是“裸对象”,和容器托管生命周期无关
Android 上 Dalvik/ART 对反射限制更严,
在高版本可能直接被拒,无替代 API
安全性不是幻觉:
不等于“绕过安全模型”
很多人以为开了反射权限就等于彻底突破安全边界,其实不是。它只是跳过了 Java 语言层的访问检查,底层仍受 JVM 安全机制约束。比如:
如果类被加载进受限模块(
等系统模块),即使
也会被模块系统拦截
SecurityManager 若启用,会调用
,拒绝则抛
某些 JDK 发行版(如 Alibaba Dragonwell、某些银行定制版)默认禁用反射权限,且无法通过参数打开
生产环境开启
(Java 16+ 默认)后,首次非法反射会警告,第二次直接报错
真正难处理的,是那些既没文档说明、又依赖隐式反射行为的第三方库——它们可能在某个小版本里悄悄改了构造逻辑,而你的反射调用就突然失效了。
getDeclaredConstructor()getDeclaredConstructor()getConstructor()NoSuchMethodExceptionsetAccessible(true)getConstructor()getDeclaredConstructor(Class...)String.classListList.classNoSuchMethodExceptionIllegalAccessExceptionsetAccessible(true)IllegalAccessExceptionConstructorIllegalAccessExceptionsetAccessible(true)InaccessibleObjectException--add-openssetAccessible(true)newInstance()SecurityExceptionsetAccessible(true)@PostConstructRuntimeExceptionInvocationTargetExceptionprivate static finalnull0@AutowiredsetAccessible(true)setAccessible(true)java.basesetAccessible(true)checkPermission(new ReflectPermission("suppressAccessChecks"))SecurityException--illegal-access=deny