上一篇我们说了Java反射之数组的反射应用 这篇我们来模拟实现那些javabean的框架(BeanUtils)的基本操作。
[一] 什么是JavaBean
JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,通过set和get方法获取。 一般我们根据这种方法命名规则,通过反射获得某个或者设置某个属性的时候,假如这个属性名为”x",那么,就会处理以下几步: 1、将x变为大写X,判断x后是否还有字母,有则首字母大写 2、在x前加get
[二] 对JavaBean的复杂内省操作
这是一种比较笨重的方式: Bean类:
1package club.leyvan.muzile; 2 3public class Bean { 4 private int x = 10; 5 private int y = 20; 6 public int getX() { 7 return x; 8 } 9 public void setX(int x) { 10 this.x = x; 11 } 12 public int getY() { 13 return y; 14 } 15 public void setY(int y) { 16 this.y = y; 17 } 18 19}
测试类:
1 public static void main(String[] args) throws Exception { 2 Bean bean = new Bean(); 3 System.out.println(getProperty(bean, "x")); 4 setProperty(bean, "y", 8); 5 System.out.println(getProperty(bean,"y")); 6 } 7 8 /** 9 * 根据属性名获得属性方法 10 * @param obj 11 * @param propertyName 12 * @return 13 * @throws Exception 14 */ 15 public static Object getProperty(Object obj,String propertyName) throws Exception{ 16 Object retVal = null; 17 //通过内省获得描述对象 18 BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); 19 //通过描述对象获得该类的所有属性描述 20 PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); 21 //迭代所有属性,获得与规则相同的方法。 22 for(PropertyDescriptor pd : pds){ 23 //如果该属性的名称与方法形参一致 24 if(pd.getName().equals(propertyName)){ 25 //则调用该属性的get方法 26 Method method = pd.getReadMethod(); 27 //get方法都是无参数的 28 retVal = method.invoke(obj); 29 } 30 } 31 32 return retVal; 33 } 34 35 /** 36 * 根据属性名设置属性的方法 37 * @param obj 38 * @param propertyName 39 * @param value 40 * @throws Exception 41 */ 42 public static void setProperty(Object obj,String propertyName,Object value) throws Exception{ 43 //通过内省获得描述对象 44 BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); 45 //通过描述对象获得该类的所有属性描述 46 PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); 47 //迭代所有属性,获得与规则相同的方法。 48 for(PropertyDescriptor pd : pds){ 49 //如果该属性的名称与方法形参一致 50 if(pd.getName().equals(propertyName)){ 51 //则调用该属性的set方法 52 Method method = pd.getWriteMethod(); 53 //set方法传入参数 54 method.invoke(obj,value); 55 } 56 } 57 }
结果:
110 28
将原本等于20的y改为了8
[三] 对JavaBean的简单内省操作
上面是一种笨拙的方式,有更为简单的方法:
1 public static void main(String[] args) throws Exception { 2 Bean bean = new Bean(); 3 System.out.println(getProperty(bean, "x")); 4 setProperty(bean, "y", 39); 5 System.out.println(getProperty(bean,"y")); 6 } 7 8 public static Object getProperty(Object obj,String propertyName) throws Exception{ 9 Object retVal = null; 10 //直接获得属性描述对象 11 PropertyDescriptor pd = new PropertyDescriptor(propertyName, obj.getClass()); 12 //根据属性,获得get方法 13 Method method = pd.getReadMethod(); 14 //调用方法 15 retVal = method.invoke(obj); 16 return retVal; 17 } 18 19 public static void setProperty(Object obj,String propertyName,Object value) throws Exception{ 20 PropertyDescriptor pd = new PropertyDescriptor(propertyName, obj.getClass()); 21 Method method = pd.getWriteMethod(); 22 method.invoke(obj, value); 23 }
结果:
110 239
本期Java反射就介绍到这,谢谢大家!