目录
反射概述
原来的开发流程:程序代码是固定的,方法的执行顺序也是固定的
源代码 -> 字节码 -> 运行
使用反射:在需要的时候执行对应对象的方法,更改了程序执行的顺序,大大提高了程序的灵活性
反射技术致力于构建通用的底层代码,让所有的模块调用,提高程序的扩展性。
什么是反射?
在程序运行过程中分析类的一种能力
反射能做什么?
-
分析类
加载并初始化一个类
查看类的所有属性和方法
-
查看并使用对象
查看一个对象的所有属性和方法
使用对象的任意属性和方法
反射的应用场景
- 构建通用的工具 搭
- 建具有高度灵活性和扩展性的系统框架
类加载器(ClassLoader)
负责将类的字节码文件(.class文件)加载到内存中,并生成对应的Class对象
Class对象
java.lang.Class类的对象,也叫字节码文件对象,每个Class对象对应一个字节码文件
类的加载时机
获取Class对象的三种方式
package com.itcast.demo12;
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
Student stu = new Student();
Class clazz1 = stu.getClass();
Class clazz2 = Student.class;
Class clazz3 = Class.forName("com.itcast.demo12.Student");
//验证这三个Class对象是同一个对象
System.out.println(clazz1 == clazz2);
System.out.println(clazz2 == clazz3);
}
}
反射方式获取构造方法并使用
Constructor对象
构造器对象,属于java.base模块,java.lang.reflect包
通过Class对象获取构造器对象
Constructor的常用方法
package com.itcast.demo12;
public class Student {
public Student() {
}
public Student(String name) {
System.out.println("您录入的name的值是:" + name);
}
private Student(int age) {
System.out.println("您录入的age的值是:" + age);
}
}
package com.itcast.demo12;
import java.lang.reflect.Constructor;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
//获取字节码文件对象
Class clazz = Class.forName("com.itcast.demo12.Student");
//获取公共的无参构造
Constructor con1 = clazz.getConstructor();
System.out.println(con1);
//获取公共的有参构造
Constructor con2 = clazz.getConstructor(String.class);
System.out.println(con2);
//获取构造器名字
String name = con2.getName();
System.out.println(name);
//获取私有的有参构造
Constructor con3 = clazz.getDeclaredConstructor(int.class);
System.out.println(con3);
//获取所有公共的构造函数
Constructor[] cons = clazz.getConstructors();
for (Constructor con : cons) {
System.out.println(con);
}
//根据构造器和参数,创建对应的Student对象
Student stu = (Student) con2.newInstance("张三");
System.out.println(stu);
}
}
反射方式获取成员方法并使用
Method对象
方法对象,属于java.base模块,java.lang.reflect包
通过Class对象获取方法
Method的常用方法
package com.itcast.demo12;
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;
}
}
package com.itcast.demo12;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
//获取字节码文件对象
Class clazz = Class.forName("com.itcast.demo12.Student");
//获取该类的构造器对象,然后创建Student类的对象
Constructor con = clazz.getConstructor();
Student stu = (Student) con.newInstance();
//System.out.println(stu);
//获取成员方法,调用
//调用公共的空参方法
Method method1 = clazz.getMethod("show1");
//打印方法对象
System.out.println(method1);
//打印方法名
System.out.println(method1.getName());
//调用此方法
method1.invoke(stu);
//调用公共的带参方法
Method method2 = clazz.getMethod("show2", int.class);
//调用方法
method2.invoke(stu, 100);
//调用私有的带参方法
Method method3 = clazz.getDeclaredMethod("show3", int.class, int.class);
//开启暴力反射
method3.setAccessible(true);
int sum = (int) method3.invoke(stu, 10, 20);
System.out.println(sum);
//获取所有成员方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
}
}
}
package com.itcast.demo12;
public class Student {
private String name;
public Student(){
}
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
package com.itcast.demo12;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
//获取字节码文件对象
Class clazz = Class.forName("com.itcast.demo12.Student");
//获取该类的构造器对象,然后创建Student类的对象
Constructor con = clazz.getConstructor();
Student stu = (Student) con.newInstance();
//System.out.println(stu);
//设置属性值
Method method1 = clazz.getMethod("setName", String.class);
method1.invoke(stu, "张三");
System.out.println(stu);
}
}
反射方式获取成员变量并使用
Field对象
域(属性、成员变量)对象,属于java.base模块,java.lang.reflect包
通过Class对象获取属性
Field的常用方法
package com.itcast.demo12;
public class Student {
public String name;
private int age;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.itcast.demo12;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
//获取字节码文件对象
Class clazz = Class.forName("com.itcast.demo12.Student");
//获取该类的构造器对象,然后创建Student类的对象
Constructor con = clazz.getConstructor();
Student stu = (Student) con.newInstance();
//链式编程
//Student student = (Student) clazz.getConstructor().newInstance();
//设置属性值
Field field1 = clazz.getField("name");
field1.set(stu, "张三");
Field field2 = clazz.getDeclaredField("age");
field2.setAccessible(true);
field2.set(stu, 28);
System.out.println(stu);
}
}