通过反射来获取某一个类的构造器可以分两步:
1.获取该类的字节码对象 (可参考文章 反射机制 )
2.从该字节码对象中去找需要获取的构造器(查看API文档)
获取所有构造器有两个方法:
1.getConstructor():获取当前Class所表示类的所有public方法
2.getDeclaredConstructor():获取所有构造器
获取指定的一个构造器的方法:
我们知道构造方法的方法名是与类名相同的,所以不能通过方法名来区分各个方法。在调用构造方法时候是用参数类型,参数个数等区分的,那这里也同样。
import java.lang.reflect.Constructor;
class User {
public User() {
}
public User(String name) {
}
private User(String name, int age) {
}
}
// 获取构造器
public class GetConstructorDemo {
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
// getAll();
getOne();
}
// 获取指定的一个构造器
private static void getOne() throws NoSuchMethodException, SecurityException {
// 1.获取构造器所在类的字节码对象
Class<User> clz = User.class;
// 2.获取clz对象中所有的构造器
Constructor<User> con = clz.getConstructor();
System.out.println(con);
con = clz.getConstructor(String.class);
System.out.println(con);
// 因为这个方法在User中是private,所以要用getDeclaredConstructor
con = clz.getDeclaredConstructor(String.class, int.class);
System.out.println(con);
}
// 获取所有的构造器
private static void getAll() {
// 1.获取构造器所在类的字节码对象
Class<User> clz = User.class;
// 2.获取clz对象中所有的构造器
// getConstructor():获取当前Class所表示类的public方法
Constructor<?>[] cs = clz.getConstructors();
System.out.println(cs.length);
for (Constructor<?> c : cs) {
System.out.println(c);
}
// getDeclaredConstructor():获取所有构造器
Constructor<?>[] cs1 = clz.getDeclaredConstructors();
System.out.println(cs1.length);
for (Constructor<?> c : cs1) {
System.out.println(c);
}
}
}
获取构造器后就可以创建对象,构造器的作用就是创建对象。
那么为什么我们不直接用new 来创建对象,而还要通过反射这么麻烦呢?
因为在框架中提供给我们的都是字符串,无法new对象。
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
//使用反射调用构造器-->创建对象
class Person {
public Person() {
System.out.println("无参构造器");
}
public Person(String name) {
System.out.println("一个参数" + name);
}
private Person(String name, int age) {
System.out.println("两个参数" + name + age);
}
}
public class CreatObjectDemo {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// new 方式
// new Person();
// new Person("Ann");
Class<Person> clz = Person.class;
//外界可访问,且没有参数,可以Class类中的newInstance()方法直接创建对象。
clz.newInstance();
// 调用public Person()
Constructor<Person> con = clz.getConstructor();
// 调用构造器的newInstance方法来创建对象,并传入实参
con.newInstance();
//注意这里要重新拿到构造器,没有这一句会报错
con=clz.getConstructor(String.class);
con.newInstance("Ann");
con=clz.getDeclaredConstructor(String.class,int.class);
//这个方法是私有的,所以要先设置当前构造器可以访问的
con.setAccessible(true);
con.newInstance("Ann",18);
}
}
//不能在CreatObjectDemo类中访问Person类中的private构造器 ,所有要setAccessible(true)。
通过反射获取方法也是同样的。