http://blog.sina.com.cn/s/blog_5d65a16901011kom.html

内省IntroSpector

JavaBean主要用于传递数据信息,其方法用于访问私有变量,且方法名符合某种规则。

    如果在两个模块之间传递信息,可以将信息封装进JavaBean中,这种对象称为“值对象”(Value Object),或“VO”。方法比较少。这些信息储存在类的私有变量中,通过set()、get()获得。

    内省主要是对JavaBean进行操作。JavaBean内部的方法要按照某种规则命名,例如void setAge(int age)、int getAge()。JavaBean可以作为普通类进行操作;普通类如果内部有set()、get()方法,也可以当做JavaBean使用。

    JavaBean的属性是通过get()和set()方法推断出来的,即去掉get、set后的字母,例如,属性为age,而不是成员变量,因为成员变量看不见。

获得属性名的规则:如果属性名的第二个字母是小写,则把第一个字母小写。例如,gettime—>time,setTime—>time,getCPU—>CPU。

    JavaBean处理的好处:

    1、JavaEE中许多地方需要使用JavaBean。

    2、JDK给JavaBean提供的API称为内省。

 

    PropertyDescriptor类

    PropertyDescriptor类表示JavaBean类通过存储器导出一个属性。主要方法:

    1、getPropertyType(),获得属性的Class对象。

    2、getReadMethod(),获得用于读取属性值的方法;getWriteMethod(),获得用于写入属性值的方法。

    3、hashCode(),获取对象的哈希值。

    4、setReadMethod(Method readMethod),设置用于读取属性值的方法;setWriteMethod(Method writeMethod),设置用于写入属性值的方法;

    导包java.bean.*;

    通过属性名获取对应的值,利用反射方法,如下:                                         

           ReflectPoint pt1 = new ReflectPoint(7,9);

              String propertyName = "x";//给一个属性,获取值

              PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());

              Method methodGetX = pd.getReadMethod();//Read对应get()方法

              Object reValue = methodGetX.invoke(pt1);

    给某个属性设置值,如下:

           String propertyName2 = "y";//给一个属性,设置值

              PropertyDescriptor pd2 = new PropertyDescriptor(propertyName2,pt1.getClass());

              Method methodSetY = pd2.getWriteMethod();//Write对应set()方法

              methodSetY.invoke(pt1,3);

       右键—》Source—》Generate Geters and Setters,创建get()和set()方法。

    选择一些代码,右键—》Refactor—》Extract Method,创建一个方法,提高复用性。  

 

    Introspector类

    将JavaBean中的属性封装起来进行操作。在程序把一个类当做JavaBean来看,就是调用Introspector.getBeanInfo()方法,得到的BeanInfo对象封装了把这个类当做JavaBean看的结果信息,即属性的信息。需要导包java.beans.*。

    getPropertyDescriptors(),获得属性的描述,可以采用遍历BeanInfo的方法,来查找、设置类的属性。

    private static Object getProperty_2(Object pt1, String propertyName) throws Exception {

               BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());

               PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();

               Object reValue = null;

               for(PropertyDescriptor pd : pds){

                     if(pd.getName().equals(propertyName)){

                            Method methodGetX = pd.getReadMethod();

                            reValue = methodGetX.invoke(pt1);

                            break;

                     }

               }

               return reValue;

        }

    通过这两个类的比较可以看出,都是需要获得PropertyDescriptor,只是方式不一样:前者通过创建对象直接获得,后者需要遍历,所以使用PropertyDescriptor类更加方便。

   

    BeanUtils工具包              

    为JavaBean提供更多、放方便的功能。

    beanutils.jar = beanutils-core.jar + beanutils-bean-collections.jar,可以通过BuildPath,添加额外的jar包,或者工程下建立lib目录,将jar包复制进来,再加载这个jar包:右键—》add to BuildPath。使用时需要导包:org.apache.commons.beanutils.BeanUtils。

    需要配合使用acpche提供的日志包:logging

    获得属性的值,例如,BeanUtils.getProperty(pt1,"x"),返回字符串

    设置属性的值,例如,BeanUtils.setProperty(pt1,"y",22),参数是字符串或基本类型自动包装。设置属性的值是字符串,获得的值也是字符串,不是基本类型。

    BeanUtils的特点:

1、对基本数据类型的属性的操作:在WEB开发、使用中,录入和显示时,值会被转换成字符串,但底层运算用的是基本类型,这些类型转到动作由BeanUtils自动完成。

2、对引用数据类型的属性的操作:首先在类中必须有对象,不能是null,例如,private Date birthday=newDate();。操作的是对象的属性而不是整个对象,例如,BeanUtils.setProperty(pt1,"birthday.time",121);

Java7的新特性:Map和JavaBean之间可以进行相互转换,key是属性,value是值。

describe:JavaBean—>Map;populate:Map—>JavaBean。例如:

    Map map = (name:Kim,age:18);

        BeanUtils.setProperty(map,"name","Kim");

    copyProperties(Object dest, Object orig) ,将一个对象的属性值复制到另一个对象的属性,需要保证属性一致。

   

    PropertyUtils类

    和BeanUtils不同在于,运行getProperty、setProperty操作时,没有类型转换,使用属性的原有类型或者包装类。