Java高级-反射
反射概述
什么是反射
在程序运行过程中分析类的一种能力
反射能做什么?
- 分析类
&empsp;&empsp;&empsp;&empsp;加载并初始化一个类
&empsp;&empsp;&empsp;&empsp;查看类的所有属性和方法 - 查看并使用对象
&empsp;&empsp;&empsp;&empsp;查看一个对象的所有属性和方法
&empsp;&empsp;&empsp;&empsp;使用对象的任意属性和方法
反射的应用场景
- 构建通用的工具
- 搭建具有高度灵活性和扩展性的系统框架
代码演示
public class ReflectDemo1 {
public static void main(String[] args) throws ClassNotFoundException {
//需求:获取class对象
//方式一
Student stu = new Student();
Class clazz1 = stu.getClass();
//方式二
Class clazz2 = Student.class;
//方式三
Class clazz3 = Class.forName("cn.itcast.demo1.Student");
//思考:如何验证这三个Class对象是同一个对象?
System.out.println(clazz1 == clazz2); //true
System.out.println(clazz2 == clazz3); //ture
}
}
//学生类
public class Student {
}
运行结果
反射方式获取构造方法并使用
代码演示
import java.lang.reflect.Constructor;
public class ReflectDemo1 {
public static void main(String[] args) throws Exception {
//需求:通过反射的方式创建:Student类型的对象
//1. 获取Student类的字节码文件对象
Class clazz = Class.forName("cn.itcast.demo2.Student");
//2. 根据第一步获取到的字节码文件对象,获取指定的构造器对象
//2.1 获取公共无参构造
Constructor con1 = clazz.getConstructor();
System.out.println(con1);
//2.2 获取公共有参构造
Constructor con2 = clazz.getConstructor(String.class);
System.out.println(con2);
//2.3 获取私有有参构造
Constructor con3 = clazz.getDeclaredConstructor(int.class);
System.out.println(con3);
//2.4 获取Student类的所有公共的构造函数
System.out.println("--------------------");
Constructor[] cons = clazz.getConstructors();
//遍历数组
for (Constructor con : cons) {
System.out.println(con);
}
//2.2 获取公共有参构造
Constructor con4 = clazz.getConstructor(String.class);
System.out.println(con4);
//获取构造器的名字,看看它是哪个类的构造
String name = con4.getName();
System.out.println(name);
//3. 根据构造器对象和参数,创建对应的Student对象
Student stu =(Student) con4.newInstance("张三");
//4. 打印结果
System.out.println(stu);
}
}
//学生类
public class Student {
//公共的无参构造
public Student() {};
//公共的带参构造
public Student(String name) {
System.out.println("您录入的name的值是:" + name);
}
//私有的带参构造
private Student(int age) {
System.out.println("您录入的age的值是:" + age);
}
}
运行结果
反射方式获取成员方法并使用
代码演示
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ReflectDemo1 {
public static void main(String[] args) throws Exception {
//需求:通过反射获取Student类中的成员方法并调用
//1. 获取Student类的字节码文件对象
Class clazz = Class.forName("cn.itcast.demo3.Student");
//2. 获取该类的构造器对象,然后创建Student类的对象
Constructor con = clazz.getConstructor();
Student stu =(Student) con.newInstance();
//System.out.println(stu);
//3. 获取该类的成员方法对象,然后调用此方法
//3.1 调用公共的空参方法
Method method1 = clazz.getMethod("show1");
//打印方法对象
System.out.println(method1);
//打印方法名
System.out.println(method1.getName());
//调用此方法
method1.invoke(stu);
System.out.println("------------------");
//3.2 公共的带参方法
Method method2 = clazz.getMethod("show2", int.class);
//调用方法
method2.invoke(stu, 100);
System.out.println("------------------");
//3.3 调用私有的带参方法
Method method3 = clazz.getDeclaredMethod("show3", int.class, int.class);
//开启暴力反射
method3.setAccessible(true);
//调用此方法
int sum =(int)method3.invoke(stu, 10, 20);
System.out.println("您录入的两个数的和是:" + sum);
System.out.println("------------------");
//3.4 获取Student类中所有的成员方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
}
}
}
public class Student {
//公共的空参方法
public void show1() {
System.out.println("我是公共的空参方法");
}
//公共的带参方法
public void show2(int a) {
System.out.println("我是公共的带参方法,您传入的a的值是:" + a);
}
//私有的带参方法
private int show3(int a, int b) {
System.out.println("我是私有的带参方法");
return a + b;
}
}
运行结果
案例:通过反射获取方法并使用
代码演示
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ReflectDemo1 {
public static void main(String[] args) throws Exception {
//需求:通过反射获取类的setter方法,使用该方法为属性赋值
//1. 通过反射获取Student类的字节码文件对象
Class clazz = Class.forName("cn.itcast.demo4.Student");
//2. 通过反射获取Student类的构造方法,并创建该类的对象
Constructor con = clazz.getConstructor();
Student stu = (Student)con.newInstance();
//3. 获取到指定的setName()方法,给Student对象设置值
Method method1 = clazz.getMethod("setName", String.class);
//调用此方法
method1.invoke(stu,"张三");
//4. 打印学生对象
System.out.println(stu);
}
}
//标准的JavaBean类,学生类
public class Student {
//成员变量
private String name;
//空参构造
public Student() {
}
//带参构造
public Student(String name) {
this.name = name;
}
//getXxx和setXxx方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//toString()方法,用来打印该对象的各个属性值的
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
运行结果
反射方式获取成员变量并使用
代码演示
import java.lang.reflect.Field;
public class ReflectDemo1 {
public static void main(String[] args) throws Exception{
//需求:通过反射获取成员变量并使用
//1. 获取Student类的字节码文件对象
Class clazz = Class.forName("cn.itcast.demo5.Student");
//2. 通过字节码文件对象获取构造器对象,然后创建学生类对象
/*Constructor con = clazz.getConstructor();
Student stu = (Student) con.newInstance();*/
Student stu = (Student)clazz.getConstructor().newInstance(); //链式编程
//3. 设置学生对象的各个属性值
//3.1 设置姓名
Field field1 = clazz.getField("name");
field1.set(stu, "李四");
//3.2 设置年龄
Field field2 = clazz.getDeclaredField("age");
//开启暴力反射
field2.setAccessible(true);
field2.set(stu, 20);
//4. 打印学生对象
System.out.println(stu);
}
}
//学生类
public class Student {
//公共属性
public String name;
//私有的属性
private int age;
//用来打印对象的各个属性值的
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
运行结果