越学习到后面,越感觉java反射机制很重要,必须精通,要不框架那块比较难自己动手实现,回过头温习一下反射机制,查漏补缺
今天尝试了一下通过反射访问和设置类的私有属性(不设置settesr和getters),比较容易理解,代码一贴就知道了
下面是po代码:
package cn.liangqinghai.reflect; public class Beans1 { public Beans1(){ System.out.println("无参构造调用"); } public Beans1(String name){ System.out.println("带参数构造函数"+name); } public String getName(){ return "getName返回值"; } /** * 设置私有属性,并没有设置setters和getters */ private String userName = "username"; private String adminName = "adminName"; }
下面是测试类:
/** * 测试反射访问属性 */ @Test public void testFields() { try { Class<?> clazz = Class.forName("cn.liangqinghai.reflect.Beans1"); // Beans1 bean = (Beans1) clazz.newInstance(); Field[] fs = clazz.getDeclaredFields(); for (Field field : fs) { // 要设置属性可达,不然会抛出IllegalAccessException异常 field.setAccessible(true); // 打印初始值 System.out.println("设置属性之前:" + field.getName() + "===" + field.get(bean)); // 设置属性值,set(Object obj, Object value) // obj - 应该修改其字段的对象 // value - 正被修改的 obj 的字段的新值(参考api) field.set(bean, "Liang"); // 打印设置属性之后的值 System.out.println("设置属性之后:" + field.getName() + "=" + field.get(bean)); } } catch (Exception e) { e.printStackTrace(); } }
最终执行结果:
无参构造调用 设置属性之前:userName===username 设置属性之后:userName=Liang 设置属性之前:adminName===adminName 设置属性之后:adminName=Liang
总结:
通过反射机制获取和设置类的私有属性就这样, 注意点: 1、属性Field要设置.setAccessible(true),不然会报IllegalAccessException异常 2、Field.set(obj,value)中,第一个参数是当前对象(参考代码中的bean实例引用)