反射位于Java提供的java.lang.reflect包下
反射:加载类,并且允许以编程的方式解剖类中的各种成分(成员变量、方法、构造器等)
反射主要用于制作框架。
反射第一步加载类,第二部获取对象
获取对象
- 获取类的字节码,即获得Class对象
- 获取类的构造器,即获得Constructor对象
- 获取类的成员变量,即获得Field对象
- 获取类的成员方法,即获得Method对象
获取Class对象的三种方法
Class c1 = 类名.class
调用Class提供方法:public static Class forName(String package)
使用类的包名
Object提供的方法:public Class getClass(); Class c3 = 对象.getClass();
获取类的构造器
采用第三、第四个方法的所需参数为所查询类的构造器的参数类型类,如String.class、int.class等。
获取构造器作用:初始化对象返回
我们使用newInstance后要强转为我们所创建的类的类型
若在使用newInstance之前使用setAccessible,则不检查构造器是否私有,等于破环封装性
获取类的成员变量
获取成员变量的作用:赋值、取值
set()的两个参数:第一个 填入类名,第二个填入要赋的值
获取类的成员方法
要单独获取某个方法时,参数要传入方法名和参数列表的类型。
获取成员方法的作用:执行
作用和应用场景
基本作用:可以得到一个类的全部成分然后操作、可以破坏封装性、适合做Java的框架,基本上主流的框架都会基于反射设计出一些通用的功能。
应用场景举例
写一个对于任意对象都可以将对象的字段名和对应的值,保存到文件中的框架
步骤:
- 定义一个方法,可以接受任意对象
- 每收到一个对象后,使用反射获取该对象的Class对象,然后获取全部的成员变量。
- 遍历成员变量,然后提取成员变量在该对象中的具体值。
- 把成员变量名、值,写入到文件中。
public class ObjectFrame{
public static void saveObject(Object obj){
PrintSteam ps = new PrintSteam(new FileOutoutSteam("文件路径", true));
Class c = obj.getClass();//获取类对象
//从这个类中提取全部成员变量
Field[] fields = c.getDeclaredFields();
//遍历
for(Field field : fields){
//获得成员变量的名字
String name = field.getName();
field.setAccessible(true);
//获得这个变量的值
String value = field.get(obj) + "";//转为字符串类型
ps.println(name + "=" + value);
}
}
}