Java的反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
简单来说,就是在程序运行期间,我们可以通过Java的反射机制来获取任意一个类的属性和方法,并且进行调用
三种方式获取类的信息
1.调用对象的getClass方法
Users users = new Users();
Class clazz = users.getClass();
2.每个类都有一个静态的class变量,通过调用这个class变量,也可以获取类的信息
Class clazz = Users.class
3.调用Class类的静态方法:forName 提示:这种方式最常用
Class clazz = Class.forName("demo.bo.Users");
上面通过反射我们已经获取到类的信息了,这些信息就包括类的构造方法、类的成员变量、类的成员方法,接下来我们就一起来使用它们吧
1.批量获取类中所有public的构造方法
Constructor[] constructors = clazz.getConstructors();
for(Constructor c : constructors){
System.out.println(c);
}
2.批量获取类中所有的构造方法,包含私有的,受保护的,默认的及公开的
Constructor[] constructors = clazz.getDeclaredConstructors();
for(Constructor c : constructors){
System.out.println(c);
}
3.获取单个为public的构造方法
/**
* 3.获取单个为public的构造方法
*/
Constructor constructor = clazz.getConstructor();
//通过获取到的构造方法来创建对象,注意,这里需要进行强转,因为返回的是Object对象
Users user = (Users)constructor.newInstance();
//如果对象的构造方法是带有参数的,那么在获取对象的构造方法时也需要传入对应的参数类型
//假设Users类有一个带有String类型参数的构造方法
Constructor constructor = clazz.getConstructor(String.class);
//使用
Users user = (Users)constructor.newInstance("张三");
4.获取单个构造方法,包含私有的、受保护的、默认的、公开的
/**
* 获取单个任意修饰符的构造方法
* 如果有参数,则同上,传入参数的类型,例:String.class、int.class
* 注意:如果获取私有的构造方法并想通过它来创建对象,
* 那么必须设置它的setAccessible(true)才行
* 否则将会运行异常
*/
Constructor c = clazz.getDeclaredConstructor();
c.setAccessible(true);
Users user = (Users) c.newInstance();
5.获取类公开的成员变量,通过类的对象.属性名方式调用
Field field = clazz.getField("name");
/**
* 对这个变量进行赋值
* 第一个参数:这个成员变量是属于哪个类的就传入哪个类的对象
* 第二个参数:name这个变量的值是什么
*/
field.set(users,"张三");
System.out.println(users.name);
6.获取类所有的成员变量,包含私有的、受保护的、默认的、公开的
Field field = clazz.getDeclaredField("name");
//设置为true,使其可以被调用和操作
field.setAccessible(true);
field.set(users,"张三");
//由于变量是私有的,所以无法通过对象.变量这种方式来调用,但是赋值是成功的,
//可以重写对象的toString方法来检测是否赋值成功,所以这里直接打印users对象
System.out.println(users);
ps:获取公共的成员变量方法同时可以获取父类的公共的成员变量,而获取私有的成员变量的时候,是不能获取父类的成员变量的
7.批量获取类中公开的成员方法,包含父类中公开的成员方法
Method[] methods = clazz.getMethods();
for(Method m : methods){
System.out.println(m);
}
8.批量获取类中所有的成员方法,不包含父类中的成员方法
Method[] methods = clazz.getDeclaredMethods();
for(Method m : methods){
System.out.println(m);
}
9.获取单个公开的成员方法
//方法名,方法参数类型
Method m = clazz.getMethod("test4", int.class);
//类的实例,参数值
m.invoke(reflectTarget, 4);
10.获取单个成员方法,可以是私有的、受保护的、默认的、公开的
//方法名,方法参数类型
Method m = clazz.getDeclaredMethod("test1", String.class);
//设置方法是否可以被访问
m.setAccessible(true);
m.invoke(reflectTarget, "方法一");