Java 反射机制中,Constructor
类是操作构造方法的核心入口。它封装了构造方法的元信息(如参数类型、修饰符)和实例化逻辑,是框架(如 Spring、MyBatis)动态创建对象的关键工具。本文基于 JDK 1.8 源码,从类结构、关键方法、设计模式、典型场景等维度,深入解析 Constructor
类的实现逻辑与设计思想。
Constructor
类被声明为 public final class Constructor
,其中泛型
表示构造方法所属类的类型(如 Constructor
对应 String
类的构造方法)。作为 final
类,Constructor
不可被继承,确保反射行为的稳定性。
其父类 Executable
是 Method
和 Constructor
的公共父类,封装了参数、异常、注解等通用逻辑(如 getParameterTypes()
、getExceptionTypes()
),体现了面向对象的“提取公共抽象”设计原则。
Constructor
类通过私有字段存储构造方法的核心信息,关键字段如下:
Class clazz
:构造方法声明所在的类(如 String.class
)。Class>[] parameterTypes
:构造方法的参数类型数组(如 {String.class, int.class}
)。int modifiers
:构造方法的修饰符(如 public
、private
,通过 Modifier
类解析)。volatile ConstructorAccessor constructorAccessor
:构造方法访问器,实际执行实例化的代理对象(懒加载创建)。Constructor root
:共享 ConstructorAccessor
的根对象(通过 copy()
方法创建副本时指向原始对象)。这些字段完整描述了构造方法的“身份”(声明类、参数)和“权限”(修饰符),是反射实例化的基础。
newInstance(Object... initargs)
:反射实例化的入口newInstance
是 Constructor
类最核心的方法,负责通过反射创建目标类的实例。其源码逻辑可分为三部分:
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, null, modifiers);
}
}
override
标志来自父类 AccessibleObject
,若为 false
(默认),需检查调用者是否有权限访问目标构造方法。Reflection.quickCheckMemberAccess
是快速检查(基于类的访问权限),若失败则通过 checkAccess
进行严格访问控制(如私有构造方法需调用 setAccessible(true)
才能访问)。if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
Java 枚举类的实例由 JVM 自动管理,反射禁止通过 newInstance
创建枚举实例(防止破坏单例性)。
ConstructorAccessor
ConstructorAccessor ca = constructorAccessor; // 读取 volatile 变量保证可见性
if (ca == null) {
ca = acquireConstructorAccessor(); // 懒加载创建
}
T inst = (T) ca.newInstance(initargs);
ConstructorAccessor
是 sun.reflect
包中的接口,实际由 NativeConstructorAccessorImpl
(本地实现)或 ConstructorAccessorImpl
(字节码生成实现)提供具体实例化逻辑。acquireConstructorAccessor
优先从 root
共享的 ConstructorAccessor
中获取(享元模式),若不存在则通过 reflectionFactory.newConstructorAccessor(this)
创建新实例,并同步到 root
链。copy()
:共享资源的副本创建Constructor<T> copy() {
if (this.root != null)
throw new IllegalArgumentException("Can not copy a non-root Constructor");
Constructor<T> res = new Constructor<>(...); // 复制所有元信息
res.root = this; // 副本的 root 指向原始对象
res.constructorAccessor = constructorAccessor; // 共享 ConstructorAccessor
return res;
}
Class.getConstructor()
等方法获取 Constructor
实例时,JVM 会创建 copy
副本,避免直接修改原始对象的 accessibility
状态(AccessibleObject
的设计要求)。root
链共享 ConstructorAccessor
,减少重复创建开销(享元模式的典型应用)。getParameterAnnotations()
:获取参数注解@Override
public Annotation[][] getParameterAnnotations() {
return sharedGetParameterAnnotations(parameterTypes, parameterAnnotations);
}
parameterAnnotations
字节数组解析注解(JVM 存储的注解二进制数据),支持运行时注解(如 @Deprecated
)的反射获取。ConstructorAccessor
的解耦设计ConstructorAccessor
是典型的代理(Proxy
)角色,隐藏了实例化的底层实现:
NativeConstructorAccessorImpl
):通过 JNI 调用本地方法,适合冷启动或低频调用。ConstructorAccessorImpl
):通过 sun.reflect.GeneratedConstructorAccessor
动态生成字节码(如 Unsafe
或 ASM
),性能接近直接调用(热点方法优化)。通过代理模式,Constructor
类无需关心具体实例化实现,只需委托给 ConstructorAccessor
,符合“开闭原则”。
root
链的资源共享copy()
方法创建的 Constructor
副本通过 root
字段指向原始对象,共享 constructorAccessor
。这种设计避免了为每个 Constructor
实例重复创建 ConstructorAccessor
,减少内存占用和初始化开销,是享元模式(Flyweight
)的典型应用。
getGenericInfo()
方法通过工厂模式创建 ConstructorRepository
(泛型信息仓库):
private transient ConstructorRepository genericInfo;
@Override
ConstructorRepository getGenericInfo() {
if (genericInfo == null) {
genericInfo = ConstructorRepository.make(getSignature(), getFactory());
}
return genericInfo;
}
CoreReflectionFactory
负责生成 GenericsFactory
,用于解析泛型签名(如 List
构造方法的泛型参数)。import java.lang.reflect.Constructor;
public class ReflectionNewInstanceDemo {
public static void main(String[] args) throws Exception {
// 获取 String 类的构造方法(参数为 char[])
Constructor<String> constructor = String.class.getConstructor(char[].class);
// 调用构造方法创建实例(参数为 ['h', 'e', 'l', 'l', 'o'])
String str = constructor.newInstance(new char[]{'h', 'e', 'l', 'l', 'o'});
System.out.println(str); // 输出:hello
}
}
public class PrivateConstructorDemo {
private PrivateConstructorDemo(String msg) {
System.out.println("Private constructor: " + msg);
}
public static void main(String[] args) throws Exception {
// 获取私有构造方法
Constructor<PrivateConstructorDemo> constructor =
PrivateConstructorDemo.class.getDeclaredConstructor(String.class);
constructor.setAccessible(true); // 突破访问限制
// 创建实例
PrivateConstructorDemo obj = constructor.newInstance("Hello Reflection");
// 输出:Private constructor: Hello Reflection
}
}
import java.util.ArrayList;
import java.util.List;
import java.lang.reflect.Constructor;
public class GenericConstructorDemo {
static class GenericClass<T> {
private T value;
public GenericClass(T value) {
this.value = value;
}
}
public static void main(String[] args) throws Exception {
// 获取泛型构造方法(参数类型为 T)
Constructor<GenericClass<String>> constructor =
GenericClass.class.getConstructor(Object.class); // 泛型擦除后参数为 Object
// 创建实例(传入 String 类型参数)
GenericClass<String> obj = constructor.newInstance("Generic Value");
System.out.println(obj.value); // 输出:Generic Value
}
}
Constructor
类是 Java 反射机制中“对象实例化”的核心入口,通过封装构造方法的元信息和代理实例化逻辑,为框架和工具提供了动态创建对象的能力。其设计兼顾了灵活性(支持任意构造方法调用)和性能(通过 ConstructorAccessor
优化热点调用)。
BeanFactory
通过反射调用构造方法实例化 Bean(如 @Autowired
依赖注入)。Constructor
实例或使用字节码框架如 Byte Buddy
优化)。setAccessible(true)
,但可能被 JVM 安全策略(如 SecurityManager
)阻止。ParameterizedType
手动解析。Constructor
类是 Java 反射机制中“对象创建”的核心组件,其源码中代理模式、享元模式的应用,以及懒加载、权限检查等细节,体现了“灵活与性能”的平衡设计。理解 Constructor
的实现逻辑,不仅能帮助我们更好地使用反射,也能为框架设计和性能优化提供关键思路。