使用反射调用构造器

通过反射来获取某一个类的构造器可以分两步:
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)。

通过反射获取方法也是同样的。

猜你喜欢

转载自blog.csdn.net/ziyonghong/article/details/81428212
今日推荐