483. Java 反射 - 调用构造器
在反射中,Constructor 类代表某个构造方法。
通过它,我们不仅可以获取构造器的 修饰符、参数类型、异常,还可以用它来 创建对象实例。
1. 定位构造器 (Locating Constructors)
和字段、方法类似,Class 提供了 4 种方式来获取构造器:
| API 方法 | 返回多个? | 包含私有构造器? |
|---|---|---|
getConstructor(Class...) |
否 | ❌ 否,只返回 public
|
getDeclaredConstructor(Class...) |
否 | ✅ 是 |
getConstructors() |
✅ 是,只返回 public
|
|
getDeclaredConstructors() |
✅ 是,包含 private
|
📌 注意:构造器不会被继承,所以只能获取该类本身声明的构造方法。
2. 示例:获取 String 类的构造器
Class<?> c = String.class;
Constructor<?>[] constructors = c.getDeclaredConstructors();
System.out.println("# constructors = " + constructors.length);
for (Constructor<?> constructor : constructors) {
System.out.println("constructor = " + constructor);
}
输出结果(JDK 23 中部分示例):
# constructors = 19
constructor = public java.lang.String(java.lang.StringBuilder)
constructor = private java.lang.String(char[],int,int,java.lang.Void)
constructor = public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
constructor = public java.lang.String(char[])
constructor = public java.lang.String(java.lang.String)
constructor = public java.lang.String()
...
📌 说明:
-
String类在 JDK 中有 19 个构造器,包括 公有 和 私有 -
getDeclaredConstructors()能拿到全部,而getConstructors()只能看到public
3. 获取特定构造器
例如,找到 接收字节数组 的构造器:
Class<?> c = String.class;
Constructor<?> constructor = c.getConstructor(byte[].class);
System.out.println("constructor = " + constructor);
输出结果:
constructor = public java.lang.String(byte[])
📌 关键点:
-
byte[].class表示字节数组类型 - 这和
int.class、String.class的用法一致
4. 调用构造器创建实例
Constructor.newInstance(Object... initargs) 可以用来创建对象。
示例:用字节数组构造 String:
byte[] data = "Hello".getBytes();
Constructor<String> constructor = String.class.getConstructor(byte[].class);
String str = constructor.newInstance(data);
System.out.println(str);
输出:
Hello
📌 说明:
- 通过反射构造出的对象和
new String(byte[])效果完全一样 - 如果构造器是私有的,需要调用
setAccessible(true)才能使用
5. 总结
- ✅
Constructor类让我们能查看和调用构造器 - ✅
getConstructors()/getDeclaredConstructors()区别 → 是否包含私有构造器 - ✅
newInstance(args...)用于 真正创建对象 - ✅ 如果构造器是私有的 → 需要
setAccessible(true) - ✅ 构造器不继承,只能访问类自身声明的