Java可通过Constructor类配合反射调用私有构造函数:先用getDeclaredConstructor()获取,再setAccessible(true)启用访问,最后newInstance()创建实例;但该操作破坏封装性,JDK9+已弃用newInstance(),需注意安全限制与异常处理。
Java 中可以通过
类配合反射机制,调用类的私有构造函数来创建对象实例,绕过编译期访问限制。这在框架开发(如 Spring、JUnit)、序列化工具或单元测试中较常见,但需谨慎使用。
获取私有构造函数
使用
获取指定参数类型的私有构造函数(注意不是
,后者只返回 public 构造器):
若无参私有构造,直接写
设置可访问性
默认无法调用私有成员,必须显式调用
禁用 JVM 访问检查:
该操作可能受 SecurityManager 限制(生产环境通常禁用)
JDK 12+ 在某些安全策略下会抛出
,需配合 JVM 参数(如
)放开模块封装
调用构造函数创建实例
使用
(JDK 9 起已标记为废弃,推荐用
的替代方式:直接调用
):
参数类型和数量必须严格匹配,否则抛出
或
若构造函数抛出异常(如
),会被包装为
,需捕获并处理其
注意事项与替代建议
反射调用私有构造函数破坏封装性,易引发维护和安全问题:
优先考虑提供 package-private 或 protected 构造器 + 工厂方法
单元测试中可用
或依赖注入替代
避免在生产代码中滥用;若必须使用,应加详细注释说明原因
注意泛型擦除:构造器参数为泛型类型时,运行时无法获取实际类型信息
ConstructorClass.getDeclaredConstructor(...)getConstructor()Constructor ctor = MyClass.class.getDeclaredConstructor(String.class, int.class); getDeclaredConstructor()setAccessible(true)ctor.setAccessible(true);InaccessibleObjectException--add-opensnewInstance(...)newInstancector.newInstance(...)MyClass obj = ctor.newInstance("hello", 42);IllegalArgumentExceptionInstantiationExceptionRuntimeExceptionInvocationTargetExceptiongetCause()@TestInstance(TestInstance.Lifecycle.PER_CLASS)