跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

如何利用反射获取类的私有构造方法并强制实例化对象

必须用getDeclaredConstructor()获取私有构造器并调用setAccessible(true),否则因访问限制或类型不匹配抛异常;反射实例化会跳过静态初始化,导致static final字段为null或默认值。 必须用
getDeclaredConstructor()
,
getConstructor()
会直接失败 私有构造器根本不会被
getConstructor()
返回——它只查
public
构造器,连 private 的影子都看不到。一调就抛
NoSuchMethodException
。真正能“看见”私有构造器的只有
getDeclaredConstructor()
,因为它返回本类**声明的所有**构造器(含 private、protected、package-private)。但注意:「看见」不等于「能用」,这步只是拿到引用。
setAccessible(true)
不是可选项,是强制前提 拿到
Constructor
对象后直接调
newInstance()
,JVM 会在运行时拦截并抛
IllegalAccessException
。Java 的访问检查机制默认生效,必须显式调用
setAccessible(true)
才能绕过。Java 9+ 模块系统下还可能触发
InaccessibleObjectException
,尤其在使用
--illegal-access=deny
启动参数时。这不是警告,是硬性门槛。 参数类型必须严格匹配,否则
NoSuchMethodException
再次出现 传给
getDeclaredConstructor()
的 Class 类型数组,必须和目标私有构造器签名完全一致。比如构造器是
private Person(String name, int age)
,就得写
getDeclaredConstructor(String.class, int.class)
。写成
Integer.class
或漏掉一个参数,都会报错。常见疏忽是基本类型和包装类混用(
int
vs
Integer
),JVM 不自动装箱。 实例化后字段可能未初始化,特别是
private static final
反射创建的对象,跳过了正常类加载流程中的静态初始化块和
static final
字段赋值逻辑。如果类里有类似
private static final List CONFIG = initConfig();
这种依赖静态方法初始化的字段,反射出来的实例中该字段仍是
null
或默认值(0、false)。这不是 bug,是反射绕过 JVM 初始化阶段的必然结果。别指望它和 new 出来的对象行为完全一致。

相关文章