Java学习 | 反射
认识反射
反射就是:加载类,并允许以编程的方式解剖类中的各种成分(成员变量、方法、构造器等)。
反射使用过程:
- 反射第一步: 加载类,获取类的字节码: Class 对象
- 获取类的构造器: Constructor对象
- 获取类的成员变量: Field对象
- 获取类的成员方法: Method对象
反射的作用:
- 基本作用:可以得到一个类的全部成分然后操作
- 可以破坏封装性。
- 最重要的用途是: 适合做 Java 的框架,基本上,主流的框架都会基于反射设计出一些通用的功能。
使用场景:例如:设计一个框架。对于任意一个对象,该框架都可以把对象的字段名和对应的值,保存到文件中去。实现步骤如下:
- 定义一个方法,可以接收任意对象。
- 每收到一个对象后,使用反射获取该对象的Class对象,然后获取全部的成员变量。
- 遍历成员变量,然后提取成员变量在该对象中的具体值。
- 把成员变量名、和其值,写出到文件中去即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36package com.atxiong.reflect;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
/**
*
* @Author Xiong
* @data 2023/8/22
* @Description 保存任意对象的字段和数据到文件中
*/
public class ObjectFrame {
public static void saveObject(Object obj) throws Exception {
PrintStream ps = new PrintStream(new FileOutputStream("./src/data.txt", true));
//获取类
Class c = obj.getClass();
String cName = c.getSimpleName();
ps.println("-----------------" + cName + "-----------------");
//获取全部成员变量
Field[] fields = c.getDeclaredFields();
//遍历每个成员变量
for (Field field : fields) {
//拿到成员变量的名字
String name = field.getName();
//拿到该成员变量的数据
field.setAccessible(true); //禁止检查访问控制
String value = field.get(obj) + "";
ps.println(name + "=" + value);
}
ps.close();
}
}
获取类
获取Class对象的三种方式:
Class c1=类名.class
- 调用Class提供方法:
public static Class forName(String package); Class c2 = Class.forName("package名字")
- Object提供的方法:
public Class getClass(); Class c3=对象.getClass();
获取类的构造器
获取类的构造器方法:
方法 | 说明 |
---|---|
Constructor<?>[] getConstructors() | 获取全部构造器(只能获取public修饰的) |
Constructor<?>[] getDeclaredConstructors() | 获取全部构造器(只要存在就能拿到) |
Constructor<T> getConstructor(Class<?>... parameter Types) | 获取某个构造器(只能获取public修饰的) |
Constructor<T> getDeclaredConstructor(Class<?>... parameter Types) | 获取某个构造器(只要存在就能拿到) |
获取类构造器的作用:初始化对象返回。
Constructor提供的方法 | 说明 |
---|---|
T newInstance(Object... initargs) | 调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回 |
public void setAccessible(boolean flag) | 设置为true,表示禁止检查访问控制(暴力反射) |
获取类的成员变量
获取类中成员变量的方法:
方法 | 说明 |
---|---|
public Field[] getFields() | 获取类的全部成员变量(只能获取public修饰的) |
public Field[] getDeclaredFields() | 获取类的全部成员变量(只要存在就能拿到) |
public Field getField(String name) | 获取类的某个成员变量(只能获取public修饰的) |
public Field getDeclaredField(String name) | 获取类的某个成员变量(只要存在就能拿到) |
获取成员变量的作用:赋值、取值。
方法 | 说明 |
---|---|
void set(Object obj, Object value) | 赋值 |
Object get(Object obj) | 取值 |
public void setAccessible(boolean flag) | 设置为true,表示禁止价差访问控制(暴力反射) |
获取类的成员方法
获取类中成员方法的方法:
方法 | 说明 |
---|---|
Method[] getMethods() | 获取类的全部成员方法(只能获取public修饰的) |
Method[] getDeclaredMethods() | 获取类的全部成员方法(只要存在就能拿到) |
Method getMethod(String name, Class<?>... parameter Types) | 获取类的某个成员方法(只能获取public修饰的) |
Method getDeclaredMethod(String name, Class<?>... parameter Types) | 获取类的某个成员方法(只要存在就能拿到) |
获取类中成员方法的作用:执行该方法。
方法 | 说明 |
---|---|
public Object invoke(Object obj, Object... args) | 触发某个对象的该方法执行 |
public void setAccessible(boolean flag) | 设置为true,表示禁止检查访问控制 (暴力反射) |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Threewood!
评论