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