基础加强____【内省JavaBean】【BeanUtils框架】
"内省"(IntroSpector)--> 了解"JavaBean" "*"JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类的方法主要用于访问私有字段 且其方法符合一定的命名规则: getXxx() setXxx(),可以通过方法名推断其功能 "*"如果在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象 (Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值, 则需要通过一些相应的方法来访问,JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。 "*"可以吧javaBean 当做普通的类来使用,但JavaBean能够带来一些额外的好处 首先,JavaBean是Java EE开发中的应用规范 JDK提供了一些对JavaBean进行操作的API"内省",比按照普通的类操作更方便 eclipse可以通过右键菜单source生成setter & getter方法 用内省的方式来读取JavaBean的属性 内省综合案例 演示用eclipse自动生成ReflectPoint类 的setter & getter方法 创建一个 PropertyDescriptor 对象来获取该属性的描述,对setter & getter进行重构 用eclipse将读取属性和设置属性方法分别抽取成方法 只要调用这个方法,并对这个方法传递一个 对象&属性名&设置值,就能完成属性修改的功能 得到BeanInfo的方式 obj.getClass() 比 类名.class 更通用 相比较为复杂的方法(内省类) 采用遍历BeanInfo的所有属性来查找和设置某个ReflectPoint对象的x属性,在程序中把一个类当做JavaBean来看待。 调用 Introspector.getBeanInfo方法,得到BeanInfo对象,该对象封装了把这个类当做JavaBean的信息 "BeanUtils 框架" 使用BeanUtils开源框架来操作JavaBean,BeanUtils框架非常有用 首先将该框架的jar包导入到eclipse工程中 下载BeanUtil包,将beanutils.jar文件copy到工程的lib目录下,将该目录添加路径buildpath-->addpath 下载Logging包,添加jar 使用BeanUtils框架的好处: (1)框架中集成了对对象进行操作的方法,可以直接使用不用再自己定义,接受的参数类型为String,避免了转数据类型的麻烦 (2)可以接收"属性面",对复合属性逐级向下查找 如birthday是Person的成员属性,Person中提供了相应的set & getBirthday方法 同时birthday是一个Date类的实例对象,date类提供了setTim方法,就可以将Date类也当做JavaBean来看待 通过修改time的属性来修改birthday,如果自己定义的话是比较繁琐的,而BeanUtil框架可以一步到位 将要修改的参数设置为 birthday.time,就能直接对该属性进行设置 BeanUtils.setProperty(pt1, "birthday.time", 6783); BeanUtils 比普通工具类强在对参数的处理上 PropertyUtils.setProperty(pt1, "x", 88);//如 88 就不能改成字符串"88",而 BeanUtils 可以 附: 对象作为一个类中的成员存在时,如果不进行初始化,在调用该属性时会抛出空指针异常 java 7 的新特性, Map 定义方式 /* Map[] map = {name:"asd" , age:22}; BeanUtils.setProperty(map, name, age); */
代码实现
package itheima.enhance; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.PropertyUtils; public class IntroSpector { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub ReflectPoint pt1 = new ReflectPoint(3, 5); //用内省的方式来读取JavaBean的属性 String propertyName = "x"; //属性名 //普通方式:"x"-->"X"-->"getX"-->MethodGetX-->... //重构get方法 Object retVal = getProperty(pt1, propertyName); System.out.println(retVal); //重构set Object value = 8; setProperty(pt1, propertyName, value); System.out.println(pt1.getX()); //使用BeanUtil开源框架提供的set & get System.out.println(BeanUtils.getProperty(pt1, "x").getClass().getName()); //(1)set.可以接收字符串,又可接收int BeanUtils.setProperty(pt1, "x", "22"); System.out.println(pt1.getX()); //(2)使用BeanUtils的另一个好处,可以接收属性面,对复合属性进行操作 // 如birthday是Person的成员属性,Person中提供了相应的setBirthday & getBirthday方法 //同时是一个Date类的实例对象,date类提供了setTim方法,就可以将Date类也当做JavaBean来看待 //通过修改time的属性来修改birthday BeanUtils.setProperty(pt1, "birthday.time", 6783); System.out.println(BeanUtils.getProperty(pt1, "birthday.time")); //Java 7 新特性 /* Map[] map = {name:"asd" , age:22}; BeanUtils.setProperty(map, name, age); */ //如 88 就不能改成字符串"88",而 BeanUtils 可以 PropertyUtils.setProperty(pt1, "x", 88); System.out.println(PropertyUtils.getProperty(pt1, "x")); } private static void setProperty(ReflectPoint pt1, String propertyName, Object value) throws IntrospectionException, IllegalAccessException, InvocationTargetException { PropertyDescriptor pd2 = new PropertyDescriptor(propertyName, pt1.getClass()); //获得该属性的描述中写入(set)属性值的方法 Method methodSetX = pd2.getWriteMethod(); methodSetX.invoke(pt1,value); } private static Object getProperty(ReflectPoint pt1, String propertyName) throws IntrospectionException, IllegalAccessException, InvocationTargetException { /* //获取该JavaBean "x"属性方法的描述 PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass()); //获得应该用于(get)读取属性值的方法 Method methodGetX = pd.getReadMethod(); //通过获取的方法创建getX()方法的当前对象所对应的值 Object retVal = methodGetX.invoke(pt1); */ //较为复杂的一种方法:调用 Introspector (内省)类的方法获取该类的 BeanInfo BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass()); //通过BeanInfo的方法获取该类所有属性的描述 PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); Object retVal = null; //对该属性集数组进行遍历查找 for(PropertyDescriptor pd : pds){ if(pd.getName().equals(propertyName)){//比较名称 Method methodGetX = pd.getReadMethod(); retVal = methodGetX.invoke(pt1); break; } } return retVal; } }