内省(Introspector)

来源:互联网 发布:c语言什么时候要用void 编辑:程序博客网 时间:2024/06/07 00:29

开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象的属性。

内省访问JavaBean属性的两种方式:

第一种:

通过PropertyDescriptor类操作Bean的属性

通过Introspector类获得Bean对象的 BeanInfo

然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),

通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,

然后通过反射机制来调用这些方法。

例:

Student sd=new Student();

       BeanInfo bif=Introspector.getBeanInfo(Student.class);

       PropertyDescriptor pdrs[]=bif.getPropertyDescriptors();

       for (PropertyDescriptor pd : pdrs) {

           if (pd.getName().equals("age")) {

              Method md = pd.getWriteMethod();

              md.invoke(sd, 12);

           }

       }

    //简便的方法

    @Test

    public void test1()throws Exception{

       Student st = new Student();

       //通过构造器 创建 PropertyDescriptor对象

PropertyDescriptor pd=newPropertyDescriptor("age",Student.class);

       Method md = pd.getWriteMethod(); //写操作

       md.invoke(st, 120);

       System.out.println(st.getAge());

       md = pd.getReadMethod();

       int value = (Integer)md.invoke(st, null); //读操作

       System.out.println(value);

     第二种:beanutils工具包

Sun公司的内省API过于繁琐,所以Apache组织结合很多实际开发中的应用场景开发了一套简单、易用的API操作Bean的属性——BeanUtils

Beanutils工具包的常用类:

        BeanUtils

        PropertyUtils

        ConvertUtils.regsiter(Converter convert, Class clazz)

        自定义转换器

例:采用BeanUtilsStudent类的name属性赋值

   @Test

    public void test1() throws Exception {

       // 1、加载Class文件

    Classcls = Class.forName("cn.csdn.beanutils.Student");

       // 2、创建bean对象

       Student bean = (Student) cls.newInstance();

       // 3、采用BeanUtilsname属性赋值

       BeanUtils.setProperty(bean, "name", "xxx");

       String value = BeanUtils.getProperty(bean, "name");

       System.out.println(value);

    }

例:Beanutils支持基本数据类型的自动转换

    @Test

    public void test2() throws Exception {

       // 1、定义class文件

Stringclass Name="cn.csdn.beanutils.Student";

       // 2、定义操作的属性

       String name = "age";

       // 3、创建class对象

       Class cls = Class.forName(className);

       // 4、创建bean对象

       Student bean = (Student) cls.newInstance();

       // 5、为操作的bean对象的name属性赋值

       BeanUtils.setProperty(bean, name, "200");

       // 6、执行输出

       System.out.println(bean.getAge());

    }

 

    @Test

    public void test3() throws Exception{

       Student st = new Student();

           BeanUtils.setProperty(st, "name", "redarmy"); // 避免了基本的数据类型转换的问题

       System.out.println(st.getName());

    }

   @Test

    public void test4() throws Exception {

       Student bean = new Student();

       BeanUtils.setProperty(bean, "birthday", new Date());

       System.out.println(bean.getBirthday());

    }

自定义转换器

例:

   @Test

    public void test5() throws Exception {

       Student bean = new Student();

    // 自带的转换器

ConvertUtils.register(new DateLocaleConverter(),Date.class);

       BeanUtils.setProperty(bean,"birthday", "1997-12-12");

       System.out.println(bean.getBirthday());

    }

@Test

public void test6() throws Exception {

       Student bean = new Student();

       //自定义转换器

       ConvertUtils.register(new Converter() {

           // 转换的类型 //转换的值

           public Object convert(Class type, Object value) {

              if (value == null) {

                  return null;

              }

              SimpleDateFormat sdi=newSimpleDateFormat("yyyy-MM-dd");

              Date dt = null;

              try {

                  dt = sdi.parse((String) value);

              } catch (ParseException e) {

                throw new ConversionException("日期格式转换有问题....");

              }

              return dt;

           }

       }, Date.class);

       BeanUtils.setProperty(bean,"birthday", "1997-11-12");

       System.out.println(bean.getBirthday());

    }

注意:

Converter接口 Android new Converter(){ //重写接口中的方法 }

相当于 public class MyConverter implements Converter{ //重写接口中的方法

    } 并且 创建了MyConveter的对象 new MyConverter();//匿名的对象

原创粉丝点击