1、什么是反射
反射:是Java被视为动态语言的关键;反射机制允许程序在运行期间,借助反射API获取任何类的全部信息,并且能够直接操作这些类的属性和方法。
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。
2、获取Class类的实例(三种方式)
- 通过类直接获取
Class c3 = Student.class;
- 通过类的一个实例,调用getClass()方法获取
People people = new Student();
Class c1 = people.getClass();
- 通过类的全路径获取(包名+类名)
Class c2 = Class.forName("ThreeClass.Student");
3、Class类的常用方法
方法名 | 说明 |
---|---|
Objecet newInstance() | 创建Class类型的一个实例 |
getName() | 获取Class对象所表示的实例名称 |
Class getSuperClass() | 返回当前Class对象的父类的Class对象 |
Class[] getinterfaces() | 获取当前Class对象的接口 |
ClassLoader getClassLoader() | 获取该类的类加载器 |
4、反射获取类的属性、方法和构造器
1. 获取类的属性
Class people = Class.forName("People");
Class user = Class.forName("user");
/*
* 1、获取类的属性
*/
//获取当前类和父类的所有public属性
Field[] fields = people.getFields();
for (Field field : fields) {
System.out.println(field);
}
//获取当前类的所以public和private属性
Field[] f2 = user.getDeclaredFields();
for (Field field : f2) {
System.out.println("Field暴力获取"+field);
}
//获取指定属性
Field name = user.getField("name"); //获取public属性
System.out.println(name);
Field age = user.getDeclaredField("age"); //获取私有的属性
System.out.println(age);
2. 获取类的方法
/*
* 2、获取类的方法
*/
//获取当前类和父类的所有public方法
Method[] m1 = user.getMethods();
for (Method method : m1) {
System.out.println(method);
}
//获取当前类所有的public和private方法
Method[] m2 = user.getDeclaredMethods();
for (Method method : m2) {
System.out.println("暴力获取"+method);
}
//获取指定的方法
Method test = user.getMethod("test"); //获取public方法
System.out.println("获取public方法"+test);
Method ptest = user.getDeclaredMethod("ptest"); //获取privata方法
System.out.println("获取private方法"+ptest);
3. 获取类构造器
/*
* 3、获取构造器
*/
//获取当前类public构造器
Constructor[] c1 = people.getConstructors();
for (Constructor constructor : c1) {
System.out.println(constructor);
}
//获取当前类public和private构造器
Constructor<?>[] c2 = people.getDeclaredConstructors();
for (Constructor<?> constructor : c2) {
System.out.println("暴力获取"+constructor);
}
//获取指定的构造器
Constructor c3 = user.getConstructor(String.class, Integer.class);
System.out.println("指定public构造器"+c3);
Constructor c4 = user.getDeclaredConstructor(null);
System.out.println("获取指定的private"+c4);
5、反射操作类的属性、方法
1. 反射创建对象
Class user = Class.forName("user");
Class people = Class.forName("People");
/*
* 1、通过反射创建对象
*/
//默认调用的无参构造
user u1 = (user) user.newInstance();
System.out.println(u1);
//使用有参构造
Constructor<?> constructor = user.getDeclaredConstructor(String.class, Integer.class);
user ul2 = (user) constructor.newInstance("小婉", 17);
System.out.println(ul2);
2. 反射执行方法
/*
*2、通过反射执行方法
* invoke(实例化的对象,方法中的参数)
*/
Method m1 = user.getDeclaredMethod("test");
m1.invoke(u1);
Method m2 = user.getDeclaredMethod("ptest");
m2.setAccessible(true); //ptest()方法为private的 ,要关闭安全检查才能执行
m2.invoke(u1);
3. 反射操作属性
/*
* 3、通过放射操作属性
* set(实例化的对象,属性值)
*/
Field f1 = people.getDeclaredField("pname");
People peo = (People) people.newInstance();
f1.setAccessible(true); //pname方法为private的 ,要关闭安全检查设置值
f1.set(peo,"小红");
System.out.println(peo.getPname());
注意点:
操作私有属性和方法时,要关闭安全权限检查,设置setAccessible(true),否则执行不了。