一、概述
反射:
- 是针对Class对象进行操作的
- 是一种针对这个Class对象解剖的技术(构造器,成员方法,成员变量)
简单说,就是对运行时获取编译后的class文件,通过反射技术,动态的去获取构造,成员变量,成员方法
反射技术实现要素及其核心思想: Class对象
利用class对象去动态获取所需的构造,成员变量,成员方法
二、获取Class的方式
1.使用类名.class -> 详看使用场景3
java
类名.class; // 直接通过类名获取类的class对象
2.使用Class.forName(),好处:在运行程序的时候,动态加载类的class字节码到内存,然后生成对象 -> 详看使用场景1
java
Class.forName("类的全限定名[带有包名的类]"); // 如com.jdbc.mysql.Driver
// 全限定名 = 顶部package后地址+类名
3.使用对象名.getClass() -> 详看使用场景2
java
对象名.getClass(); // 直接通过对象名来创建class对象,用于创建具体对象后
易错纠正:不存在 对象名.class(),正确写法为 对象.getClass()
三、使用场景
场景1:读取配置文件,使用了获取类输入流来读取配置,再使用Class.forName()动态加载类
先创建好一个配置文件student.ini在src目录下
properties
className=com.mysql.jdbc.Driver
之后在Main类中
java
Properties prop = new Properties();
prop.load(Main.class.getClassLoader().getResourceAsStream("bean.properties"));//读配置
String className = prop.getProperty("className");//通过Key找value
Class.forName(className); // 动态的加载Class对象
场景2:当方法中是形参传递的是对象需要获取class的时候
java
public void method(Student stu){
Class<Student> stucls = stu.getClass();
}
场景3:当明确类名的时候
java
类名.class;直接得到class对象
对于当前对象获取class,可以直接使用this.getClass()来替代类名.class
四、通过类加载器得到构造器(Constructor)
成员方法说明
成员方法1.得到public构造器对象
java
class对象.getConstructor(); // 只能获取public无参构造
class对象.getConstructor(参数类型.class); // 获取public有参构造
成员方法2.得到任意权限构造器对象(包含私有)
java
class对象.getDeclaredConstructor();
成员方法3:调用构造创建对象
java
构造器对象.newInstance();
案例1:使用构造器创建Student对象
先创建javabean的对象Student
java
@Data // get、set、toString
@AllArgsConstructor // 全参构造
@NoArgsConstructor // 无参构造
public class Student {
private String name;
private int age;
}
1)通过无参构造创建对象
java
// 得到class的对象
Class<? extends Student> aClass = new Student().getClass();
// 得到无参构造器
Constructor<? extends Student> constructor = aClass.getConstructor();
// 通过构造器创建对象
Student student = constructor.newInstance();
student.setName("zhangsan");
student.setAge(13);
System.out.println(student.toString());
2)通过带参构造创建对象
java
Class<? extends Student> aClass = new Student().getClass();
// 得到带参构造器,并指明构造的数据类型
Constructor<? extends Student> constructor = aClass.getConstructor(String.class,int.class);
// 传入参数创建对象
Student student = constructor.newInstance("张三",12);
System.out.println(student.toString());
3)暴力反射获取私有构造器
java
// 获取私有构造器
Constructor<? extends Student> decConstructor = aClass.getDeclaredConstructor();
// 关闭权限校验,暴力访问
decConstructor.setAccessible(true);
// 创建对象
Student student = decConstructor.newInstance();
五、反射操作成员变量(Field)
核心方法区分
getField("变量名"):仅获取public公开成员变量getDeclaredField("变量名"):获取所有权限成员变量(private/protected/public)
核心操作方法
java
field.setAccessible(true); // 暴力反射,解除私有权限限制
field.set(对象, 赋值); // 给对象的成员变量赋值
field.get(对象); // 获取对象的成员变量值
完整案例:反射操作私有成员变量
java
// 1.获取Class对象
Class<Student> studentClass = Student.class;
// 2.获取私有成员变量name
Field nameField = studentClass.getDeclaredField("name");
// 3.暴力解除权限
nameField.setAccessible(true);
// 4.创建空对象
Student student = studentClass.newInstance();
// 5.给私有变量赋值
nameField.set(student, "李四");
// 6.获取变量值
String name = (String) nameField.get(student);
System.out.println(name);
六、反射操作成员方法(Method)
核心方法区分
getMethod("方法名",参数类型.class):仅获取public公开方法getDeclaredMethod("方法名",参数类型.class):获取所有权限方法(包含私有)
核心执行方法
java
method.setAccessible(true); // 暴力反射(私有方法必须加)
method.invoke(对象, 方法参数); // 执行方法,返回方法返回值
完整案例:反射调用get/set方法、自定义方法
java
// 1.获取Class对象
Class<Student> studentClass = Student.class;
Student student = studentClass.newInstance();
// 2.获取setName公开方法
Method setName = studentClass.getMethod("setName", String.class);
// 3.执行set方法赋值
setName.invoke(student, "王五");
// 4.获取getName公开方法并执行
Method getName = studentClass.getMethod("getName");
String resName = (String) getName.invoke(student);
System.out.println(resName);
私有方法调用案例
java
// 获取私有方法
Method privateMethod = studentClass.getDeclaredMethod("私有方法名");
// 解除权限
privateMethod.setAccessible(true);
// 执行私有方法
privateMethod.invoke(student);
七、反射核心必背规则(考试/面试高频)
- getXXX() :只能获取 public 权限的构造、变量、方法
- getDeclaredXXX() :可以获取 所有权限(private/默认/protected/public)
- 所有私有资源操作必须加:setAccessible(true),否则报错权限不足
- 反射全部API均抛出编译时异常,代码必须try-catch捕获
- Class.forName() 常用于框架配置文件加载、解耦
- 反射最大特点:编译期不知道类型,运行期动态操作
八、反射所有核心API汇总
1. Class类常用方法
- 获取构造器:getConstructor() / getDeclaredConstructor()
- 获取成员变量:getField() / getDeclaredField()
- 获取成员方法:getMethod() / getDeclaredMethod()
- 创建对象:newInstance()
2. Constructor构造器
- newInstance():实例化对象
3. Field成员变量
- set():赋值
- get():取值
- setAccessible():暴力反射
4. Method成员方法
- invoke():执行方法
- setAccessible():暴力反射