java之内省技术

来源:互联网 发布:雪人翻译软件 编辑:程序博客网 时间:2024/06/05 01:02
一.为什么要学内省?
开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以SUN公司开发了一套API,专门用于操作java对象的属性。
什么是JavaBean和属性的读写方法?
通过内省技术访问(java.beans包提供了内省的API)JavaBean的两种方式。
通过PropertyDescriptor类操作Bean的属性

通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法。

PropertyDescriptor顾名思义,就是属性描述之意。它通过反射
快速操作JavaBean的getter/setter方法。
重要方法:getWriteMethod() – 获取setter方法,返回Method对像
getReadMethod() – 获取getter方法,返回Method对像

/* * Introspector构建一个BeanInfo对象。 * BeanInfo将一个类的所有属性进行了封装 * //属性描述器PropertyDescriptor[] pds = bf.getPropertyDescriptors();PropertyDescriptor对象: Method getReadMethod()           获得应该用于读取属性值的方法。   Method getWriteMethod()           获得应该用于写入属性值的方法。  * */@Testpublic void test1() throws Exception{//将Student中的所有属性封装到BeanInfo对象中BeanInfo bf = Introspector.getBeanInfo(Student.class);//属性描述器PropertyDescriptor[] pds = bf.getPropertyDescriptors();//System.out.println(pds.length);for (PropertyDescriptor pd : pds) {System.out.println(pd.getName());}}@Testpublic void test2() throws Exception{Student stu = new Student();//得到指定的属性对象PropertyDescriptor pd = new PropertyDescriptor("name", Student.class);Method setter = pd.getWriteMethod();//得到setter方法:setName()setter.invoke(stu, "tom");Method getter = pd.getReadMethod(); //得到getter方法:getName()System.out.println(getter.invoke(stu, null));}@Testpublic void test3() throws Exception{Student stu = new Student();//得到指定的属性对象PropertyDescriptor pd = new PropertyDescriptor("age", Student.class);Method setter = pd.getWriteMethod();//得到setter方法:setName()setter.invoke(stu, 18);Method getter = pd.getReadMethod(); //得到getter方法:getName()System.out.println(getter.invoke(stu, null));}


二. Apache组织开发了一套用于操作JavaBean的API,这套API考虑到了很多实际开发中的应用场景,因此在实际开发中很多程序员使用这套API操作JavaBean,以简化程序代码的编写。
Beanutils工具包的常用类:
BeanUtils
PropertyUtils
ConvertUtils.regsiter(Converter convert, Class clazz)
自定义转换器
public class Demo2 {@Testpublic void test1() throws Exception{Student stu = new Student();BeanUtils.setProperty(stu, "name", "张三"); //给属性赋值String s = BeanUtils.getProperty(stu, "name");System.out.println(s);}@Testpublic void test2() throws Exception{Student stu = new Student();//BeanUtils默认支持8种基本数据类型,自动转换BeanUtils.setProperty(stu, "age", "18"); //给属性赋值String s = BeanUtils.getProperty(stu, "age");System.out.println(s);}@Testpublic void test3() throws Exception{Student stu = new Student();//注册类型转换器ConvertUtils.register(new DateLocaleConverter(), Date.class);BeanUtils.setProperty(stu, "birthday", "1990-11-12"); //给属性赋值String s = BeanUtils.getProperty(stu, "birthday");System.out.println(s);}@Testpublic void test4() throws Exception{Student stu = new Student();//注册类型转换器ConvertUtils.register(new Converter() {public Object convert(Class type, Object value) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");if(value instanceof String){String v = (String) value;try {return sdf.parse(v);} catch (ParseException e) {throw new RuntimeException(e);}}return null;}}, Date.class);BeanUtils.setProperty(stu, "birthday", "1995-11-12"); //给属性赋值String s = BeanUtils.getProperty(stu, "birthday");System.out.println(s);}@Testpublic void test5() throws Exception{//Map m = new HashMap();m.put("name", "张三"); //key名一定要与对象中的变量名一致m.put("age", "18"); //key名一定要与对象中的变量名一致m.put("birthday", "1992-05-12"); //key名一定要与对象中的变量名一致Student stu = new Student();ConvertUtils.register(new DateLocaleConverter(), Date.class);BeanUtils.populate(stu, m); //将Map属性自动放到Bean中System.out.println(stu.getName());}}



2 0
原创粉丝点击