目录
前言
之前学习了反射创建对象,获得类中 成员变量,成员方法,构造方法。今天做一些关于反射知识运用的练习。
反射的作用:动态的创建对象 和访问 类中信息
练习
1 保存信息
使用反射 要求对任意一个对象,都可以把对象 的所有的字段和值,保存到文件中去。
在IDEA 中 创建Student 类,Teacher 类
使用到的知识点有
反射
- 获取成员变量
IO流 传输数据
- 字符缓存流 BufferWriter 写入文件
代码如下
package fs.exerise01; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; public class Test { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, IOException { // 使用反射 创建 Student 对象 Class<?> aClass = Class.forName("fs.exerise01.Student"); Student student= (Student) aClass.newInstance(); student.setName("张三"); student.setAge(18); student.setGender('男'); student.setHeight(1.75); student.setHobby("打球"); /* 第二种创建方法 获得指定构造方法创建对象 Constructor<?> constructor = aClass.getConstructor(String.class, int.class, char.class, double.class, String.class); Student student1 = (Student) constructor.newInstance("张三", 18, '男', 1.75, "打球"); System.out.println(student1); */ // 获得指定构造方法创建Teacher对象 Class<?> aClass1 = Class.forName("fs.exerise01.Teacher"); Constructor<?> declaredConstructor = aClass1.getDeclaredConstructor(String.class, double.class); Teacher teacher = (Teacher) declaredConstructor.newInstance("张三", 5000); writeData(student); } // 创建一个方法 把 类中的字段和值 写入 a.txt文件 public static void writeData(Object obj) throws IOException { Class<?> aClass = obj.getClass(); Field[] declaredFields = aClass.getDeclaredFields(); BufferedWriter bw=new BufferedWriter( new FileWriter("D:\\GPT浏览器下载\\IDEA代码\\日常代码集\\exerise-reflect03\\src\\main\\java\\fs\\exerise01\\a.txt")); for (Field declaredField : declaredFields) { // 字段的名字 String name = declaredField.getName(); // 字段的值 /* 调用getDeclaredFields方法 可以获得所有字段,包括私有字段 调用 setAccessible方法 可以访问私有字段 */ declaredField.setAccessible(true); try { Object o = declaredField.get(obj); bw.write(name+" = "+o); bw.newLine(); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } bw.flush(); bw.close(); } }
运行Student 类中的属性
运行结果
运行Teacher 类中的属性
只需修改一处地方
writeData(teacher);
运行结果
2 跟配置文件结合 动态的创建对象和 调用方法
在IDEA 中 创建 Teacher 类 和 Student 类 除了一些基本的配置外 还添加两个方法 study方法 和 teach 方法
要求:通过在配置文件 添加 全限定类名【目标类的路径,一般是 包名.类名 的方式】 和 方法名 ,可以动态调用 某类中 某个方法
思路
1 读取配置文件
2 获得成员方法 对象,获得目标类对象
3 调用 invoke 方法 执行 成员方法
调用 Student 类中 的 study 方法
package fs.exerise02; import java.io.IOException; import java.lang.reflect.Method; import java.util.Properties; public class Test { public static void main(String[] args) { //读取配置文件 Properties props = new Properties(); try { props.load(Test.class.getClassLoader().getResourceAsStream("reflect.properties")); String className = props.getProperty("className"); String methodName = props.getProperty("method"); // 创建 Student 的字节码文件对象 Class<?> cls = Class.forName(className); // 得到 成员方法的 对象 Method method = cls.getDeclaredMethod(methodName); // 创建 Student 对象 Student student = (Student) cls.newInstance(); //设置访问权限 method.setAccessible(true); // 调用成员方法 method.invoke(student); } catch (Exception e) { throw new RuntimeException(e); } } }
运行结果
调用 Teacher 类中 的teach 方法
只需要修改配置文件 和Test 测试类 创建Teacher 对象
// 创建 Teacher 对象 Teacher teacher = (Teacher) cls.newInstance(); //设置访问权限 method.setAccessible(true); // 调用成员方法 method.invoke(teacher);
运行结果