先创建好一个JavaBean对象。在一般的JavaBean基础上再加上了Student(String name)和Student(int age)两个构造函数。
package com.example.myreflect2;
public class Student {
private String name;
private int age;
public Student() {
// 默认构造函数
System.out.println("调用默认构造函数");
}
//新增的两个有参构造函数
private Student(String name) {
this.name = name;
}
protected Student(int age) {
this.age = age;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
1.获取公有构造方法
先获取类的字节码文件对象。
//1. 全类名 获取字节码文件对象
Class<?> clazz = Class.forName("com.example.myreflect2.Student");
System.out.println("字节码文件对象: "+clazz);
然后使用getConstructors()方法来获取公有构造方法。
//2. 获取公有构造方法
System.out.println("===========获取公有构造方法===========");
Constructor<?>[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors){
System.out.println(constructor);
}
输出结果:
2.获取所有构造方法
使用getDeclaredConstructors()方法获取所有构造方法。
Declared的意思是被声明的
System.out.println("===========获取所有构造方法===========");
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor constructor : declaredConstructors){
System.out.println(constructor);
}
输出结果:
3.获取单个的构造方法
使用getDeclaredConstructor()方法获取单个的构造方法。注意这里和获取所有的方法的差别是Constructor是单数。然后这个方法获取某个构造方法是通过输入形参的类来得到的。
//获取单个构造方法
System.out.println("===========获取单个构造方法===========");
Constructor<?> defaultCons = clazz.getDeclaredConstructor();
Constructor<?> cons2 = clazz.getDeclaredConstructor(String.class);
Constructor<?> cons3 = clazz.getDeclaredConstructor(int.class);
Constructor<?> allArgsCons = clazz.getDeclaredConstructor(String.class,int.class);
System.out.println("defaultCons: "+defaultCons);
System.out.println("cons2: "+cons2);
System.out.println("cons3: "+cons3);
System.out.println("allArgsCons: "+allArgsCons);
输出结果:
4.获取构造方法的权限修饰符
关于Java反射机制中获取的权限修饰符,获取的其实是数字。
权限和数字的对应关系如下:
权限修饰符(Modifier) | 数字 |
---|---|
abstract | 1024 |
final | 16 |
interface | 512 |
native | 256 |
private | 2 |
protected | 4 |
public | 1 |
static | 8 |
strict | 2048 |
synchronized | 32 |
transient | 128 |
volatile | 64 |
为什么这些数字不是1、2、3、4……呢?
据说是因为使用2的次方来表示可以和计算机更高效率地进行交互。
通过getModifiers()获取构造方法的权限修饰符
//获取构造方法的权限修饰符
System.out.println("===========获取构造方法的权限修饰符===========");
int modifiers = defaultCons.getModifiers();
System.out.println("defaultCons的权限修饰符数值: "+modifiers);
输出结果:
5.获取构造方法的形参列表
通过getParameters()可以获取构造方法的形参列表
//获取构造方法的形参列表
System.out.println("===========获取构造方法的形参===========");
Parameter[] parameters = allArgsCons.getParameters();
for (Parameter parameter : parameters){
System.out.println(parameter);
}
输出结果:
6.通过构造方法创建对象
讲这么多,我们费劲周折获取的构造方法要拿来干嘛呢?
当然是拿来创建对象!
//通过构造方法创建对象
System.out.println("===========通过构造方法创建对象===========");
Student stu = (Student) allArgsCons.newInstance("hangman", 20);
System.out.println(stu);
输出结果:
完整代码
package com.example.myreflect2;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;
public class MyReflectDemo2
{
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//1. 全类名 获取字节码文件对象
Class<?> clazz = Class.forName("com.example.myreflect2.Student");
System.out.println("字节码文件对象: "+clazz);
//2. 获取公有构造方法
System.out.println("===========获取公有构造方法===========");
Constructor<?>[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors){
System.out.println(constructor);
}
//3. 获取所有构造方法
System.out.println("===========获取所有构造方法===========");
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor constructor : declaredConstructors){
System.out.println(constructor);
}
//获取单个构造方法
System.out.println("===========获取单个构造方法===========");
Constructor<?> defaultCons = clazz.getDeclaredConstructor();
Constructor<?> cons2 = clazz.getDeclaredConstructor(String.class);
Constructor<?> cons3 = clazz.getDeclaredConstructor(int.class);
Constructor<?> allArgsCons = clazz.getDeclaredConstructor(String.class,int.class);
System.out.println("defaultCons: "+defaultCons);
System.out.println("cons2: "+cons2);
System.out.println("cons3: "+cons3);
System.out.println("allArgsCons: "+allArgsCons);
//获取构造方法的权限修饰符
System.out.println("===========获取构造方法的权限修饰符===========");
int modifiers = defaultCons.getModifiers();
System.out.println("defaultCons的权限修饰符数值: "+modifiers);
//获取构造方法的形参列表
System.out.println("===========获取构造方法的形参===========");
Parameter[] parameters = allArgsCons.getParameters();
for (Parameter parameter : parameters){
System.out.println(parameter);
}
//通过构造方法创建对象
System.out.println("===========通过构造方法创建对象===========");
Student stu = (Student) allArgsCons.newInstance("hangman", 20);
System.out.println(stu);
}
}