反射的基本概念
反射是指在程序运行时动态获取类型信息并操作对象的能力。通过反射,可以检查类、接口、字段和方法,甚至在运行时调用方法或修改字段值。反射常用于框架设计、动态代理、依赖注入等场景。
生活类比
-
正常写代码 :你提前知道 有个类
Person
,直接new Person()
调用。 -
反射 :你运行时 才拿到一个
.class
文件,不知道类名,但你能:-
查出它叫啥、有哪些方法、哪些字段
-
临时创建它的对象
-
调用它的私有方法/字段(破封装)
-
反射的常见操作
获取Class对象(三种方式)
java
// 通过包名+类名获取
Class<?> clazz1 = Class.forName("java.lang.Student");//括号里面是全类名
// 通过类名获取
Class<?> clazz2 = Student.class;
// 通过对象获取
Student s=new Student();
Class<?> clazz3 =s.getClass;
反射中获取构造方法
获取构造方法的基本步骤
通过反射获取类的构造方法,需要使用Class
类的getConstructors()
或getDeclaredConstructors()
方法。前者返回所有公共构造方法,后者返回所有声明的构造方法(包括私有构造方法)。
java
Class<?> clazz = MyClass.class;
Constructor<?>[] publicConstructors = clazz.getConstructors();
Constructor<?>[] allConstructors = clazz.getDeclaredConstructors();
获取特定参数的构造方法
如果需要获取带有特定参数类型的构造方法,可以使用getConstructor()
或getDeclaredConstructor()
方法。参数类型以Class
对象数组的形式传入。
java
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(String.class);
访问私有构造方法
私有构造方法无法直接通过getConstructor()
获取,需要使用getDeclaredConstructor()
并调用setAccessible(true)
来绕过访问限制。
java
Constructor<?> privateConstructor = clazz.getDeclaredConstructor();
privateConstructor.setAccessible(true);
Object instance = privateConstructor.newInstance();
反射获取成员变量
反射获取成员变量
获取所有成员变量
使用Class.getDeclaredFields()
方法可以获取类中声明的所有成员变量(包括私有变量,但不包括继承的变量):
java
Class<?> clazz = MyClass.class;
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
System.out.println(field.getName());
}
获取指定成员变量
通过Class.getDeclaredField(String name)
可以获取指定名称的成员变量:
java
Field field = clazz.getDeclaredField("fieldName");
获取公有成员变量
使用Class.getFields()
可以获取所有公有成员变量(包括继承的):
java
Field[] publicFields = clazz.getFields();
访问私有成员变量
要访问私有成员变量,需要先调用Field.setAccessible(true)
:
java
Field privateField = clazz.getDeclaredField("privateField");
privateField.setAccessible(true);
Object value = privateField.get(instance);