反射
Java 反射(Reflection)
反射(Reflection)是 Java 提供的强大机制,允许程序在运行时动态获取类的信息、操作类的属性和方法(包括私有、继承的成员)。它广泛应用于框架(如 Spring、Hibernate)、动态代理、测试工具等场景。
1. 反射的核心类
| 类 | 说明 |
|---|---|
Class<T> |
表示一个类或接口,反射的入口 |
Field |
表示类的成员变量(属性) |
Method |
表示类的方法 |
Constructor |
表示类的构造方法 |
2. 获取 Class 对象的 3 种方式
// 方式1:类名.class
Class<?> clazz1 = String.class;
// 方式2:对象.getClass()
String str = "Hello";
Class<?> clazz2 = str.getClass();
// 方式3:Class.forName("全限定类名")
Class<?> clazz3 = Class.forName("java.lang.String");
3. 常用方法
(1)Class
| 方法 | 说明 |
|---|---|
clazz.getName()、clazz.getCanonicalName() |
获取类全限定名 区别:如果是内部类,这俩方法返回不一样 |
clazz.getSimpleName() |
获取类名 |
clazz.isInterface() |
是否是接口 |
clazz.getInterfaces() |
获取所有实现的接口 |
clazz.getSupercalss() |
获取父类 直接父类,爷爷辈获取不了 |
clazz.newInstance() |
使用无参构造创建实例 没有无参构造会报错 |
clazz.getFields()、clazz.getField(字段名)clazz.getDeclaredFields()、clazz.getDeclaredField(字段名) |
获取成员变量 带 Declared:能获取私有,但不包括继承 不带 Declared:只能获取 public,但包括继承 |
clazz.getMethods()、clazz.getMethod(方法名, 可变参数)clazz.getDeclaredMethods()、clazz.getDeclaredMethod(方法名, 可变参数) |
获取成员方法 同上,也根据 Declared 分为两组 参数是可变参数,可传任意类型的 Class 比如: clazz.getMethod("draw", int.class, String.class) |
(2)Field
| 方法 | 说明 |
|---|---|
setAccessible(true) |
私有变量可访问(方法也适用) |
set(目标对象, 值) |
修改变量的值 对于 final 字段不会报错,但实际上该字段的值不会改变 |
get(目标对象) |
获取变量的值 |
getName() |
获取属性名称 |
getType() |
获取属性类型 也是一个 Class 对象 |
isEnumConstant() |
属性是否是枚举 |
(3)Method
| 方法 | |
|---|---|
invoke(目标对象, 可变参数) |
执行方法 |
getReturnType() |
获取方法返回值类型 是一个 Class 对象 |
4. 示例
(1)获取并操作属性(包括私有属性)
import java.lang.reflect.Field;
class Person {
private String name;
public int age;
}
public class Main {
public static void main(String[] args) throws Exception {
Class<?> clazz = Person.class;
Person person = new Person();
// 获取public属性
Field ageField = clazz.getField("age");
ageField.set(person, 25); // 设置值
System.out.println(ageField.get(person)); // 获取值
// 获取private属性(需设置可访问性)
Field nameField = clazz.getDeclaredField("name");
nameField.setAccessible(true); // 解除私有限制
nameField.set(person, "Alice");
System.out.println(nameField.get(person));
}
}
(2)调用方法(包括私有方法)
import java.lang.reflect.Method;
class Calculator {
private int add(int a, int b) {
return a + b;
}
public int multiply(int a, int b) {
return a * b;
}
}
public class Main {
public static void main(String[] args) throws Exception {
Class<?> clazz = Calculator.class;
Calculator calc = new Calculator();
// 调用public方法
Method multiplyMethod = clazz.getMethod("multiply", int.class, int.class);
int result = (int) multiplyMethod.invoke(calc, 3, 4); // 12
// 调用private方法
Method addMethod = clazz.getDeclaredMethod("add", int.class, int.class);
addMethod.setAccessible(true);
int sum = (int) addMethod.invoke(calc, 2, 3); // 5
}
}
(3)操作继承的属性和方法
class Parent {
protected String familyName = "Smith";
}
class Child extends Parent {
private String nickname = "Tom";
}
public class Main {
public static void main(String[] args) throws Exception {
Class<?> clazz = Child.class;
Child child = new Child();
// 获取继承的protected属性
Field familyNameField = clazz.getSuperclass().getDeclaredField("familyName");
familyNameField.setAccessible(true);
System.out.println(familyNameField.get(child)); // Smith
// 获取子类私有属性
Field nicknameField = clazz.getDeclaredField("nickname");
nicknameField.setAccessible(true);
System.out.println(nicknameField.get(child)); // Tom
}
}

浙公网安备 33010602011771号