目录
作用
- 基本作用:可以得到一个类的全部成分然后操作。
- 可以破坏封装性。
- 最重要的用途是:适合做Java的框架,基本上,主流的框架都会基于反射设计出一些通用的功能。
通过反射能够获取到一个类的全部成分,包括其属性、方法、构造函数等。这意味着可以在运行时动态地了解和操作类的结构和行为。
说它能破坏封装性,是因为正常情况下,类的私有成员是不应该被外部直接访问和操作的,但反射却提供了一种途径能够绕过这种限制。
其最重要的用途在于适合构建 Java 框架。例如,许多主流框架利用反射来实现通用功能。比如,框架可以通过反射自动为对象进行属性赋值、调用对象的方法,或者根据配置动态地创建类的实例等。这样就大大提高了框架的灵活性和通用性,开发者在使用框架时能够更方便地进行定制和扩展。
应用场景
案例需求
使用反射做一个简易版的框架
- 需求:对于任意一个对象,该框架都可以把对象的字段名和对应的值,保存到文件中去。
对于这个案例,如果不使用框架,对于每个不同的对象,都需要手动编写代码来获取其字段名和对应的值,并将其保存到文件中。这样会导致代码重复且不灵活,难以应对大量不同类型的对象。而使用反射构建的框架,可以以一种通用的方式处理任意对象,提高了代码的复用性和可维护性。
实现步骤
- 定义一个方法,可以接收任意对象。
- 每收到一个对象后,使用反射获取该对象的class对象,然后获取全部的成员变量。
- 遍历成员变量,然后提取成员变量在该对象中的具体值。
- 把成员变量名、和其值,写出到文件中去即可。
代码实现
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
public class ObjectFrame{
//目标:保存任意对象的字段和其数据到文件中去
public static void saveObject(Object obj) throws Exception{
PrintStream ps = new PrintStream(new FileOutputStream("src/user/reflectTest/data.txt",true));
//obj是任意对象
Class c = obj.getClass();
//可以先拿出简易名字
String cName = c.getSimpleName();
ps.println("---------------" + cName + "---------------");
//2.从这个类中提取它的全部成员变量
Field[] fields = c.getDeclaredFields();
//3.遍历每个成员变量
for(Field field:fields){
//4.拿到成员变量的名字
String name = field.getName();
//5.拿到这个成员变量在对象中的数据。
field.setAccessible(true); //禁止检查访问权限
String value = field.get(obj) + "";
//写入文件
ps.println(name + " = " + value);
}
//记得关闭流
ps.close();
}
}
随便拿两个类出来创建对象
运行之后查看data.txt文件:
END
学习自:黑马程序员——Java课程