• 内省(一)之Introspector、BeanInfo、PropertyDescriptor


      内省(Introspector)是专门用来操作JavaBean属性的。不是所有的字段(Field)都能被称之为属性,只有某些字段具有getXXXsetXXX方法的才能称之为属性,当然要称为是一个Bean还需要有一个无参的构造器,而内省就是对这些属性进行操作。

      我们先来看一个例子来数一数Javabean的属性:

     1 public class Person {
     2     private String name;
     3     private int age;
     4     
     5     public String getName() {
     6         return name;
     7     }
     8     public void setName(String name) {
     9         this.name = name;
    10     }
    11     public int getAge() {
    12         return age;
    13     }
    14     public void setAge(int age) {
    15         this.age = age;
    16     }
    17     
    18     public String getAbc() {
    19         return null;
    20     }
    21 }

      这里面一共有多少属性呢?

      答案是4个,除了两个私有字段提供了get或set 方法成为了这个类的属性之外,还有外加的一个getXXX(那么属性为xXX),最后还有一个从Object类中继承的getClass方法(属性为class),所以Person中含有4个属性。

      回归到内省,当然仅仅操作是属性,可以按操作字段一样采用反射,但是采用内省会更加专业。

      在JavaAPI中有专门的一个类封装了内省的操作,这个类就是Introspector类,通过getBeanInfo(…)方法就可以将某个类中的属性封装到一个BeanInfo类中。

      取得BeanInfo对象后就相当于取得某个类的所有属性,那么再调用BeanInfo对象中的getPropertyDescriptors()方法获得PropertyDescriptor[]数组对象,每个数组中的元素都是PropertyDescriptor实例(属性描述器),而PropertyDescriptor实例封装了每个属性特有的一些性质,比如调用getReadMethod()方法就能获得这个属性的get方法Method,调用getWriteMethod()方法就能获得这个属性的set方法Method。

      通过一段简单的代码来测试一下刚才Person这个bean对象到底有多少个属性:

    1 Person p = new Person();
    2 BeanInfo beanInfo = Introspector.getBeanInfo(p.getClass());
    3 PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
    4         for(PropertyDescriptor pd:pds) {
    5             System.out.println(pd.getName());
    6         }

    控制台观察:

      

    可以看到确实是有4个属性。

      如果我们不想有父类继承的某些get或set方法而继承下来的属性,比如上述的class,那么我们在最开始使用Introspector. getBeanInfo时可以使用对应的参数列表:

    当然这个方法也可以不需要某一级以上的父类属性,非常灵活。

      如果想直接操作一个bean的某个具体属性,那么其实我们可以直接使用属性描述器PropertyDescriptor的构造函数:

      

    比如我想操作上述Person类的age属性:

    1   PropertyDescriptor pd = new PropertyDescriptor("age", Person.class);
    2   Person p = new Person();
    3   Method setAgeMethod = pd.getWriteMethod();
    4   setAgeMethod.invoke(p,25);
    5   Method getAgeMethod = pd.getReadMethod();
    6   System.out.println(getAgeMethod.invoke(p, null));

    输出:25

      当然,获得某个属性的属性描述器(PropertyDescriptor),调用getPropertyType方法还能知道该属性的类型:

    1   PropertyDescriptor pd = new PropertyDescriptor("age", Person.class);
    2   System.out.println(pd.getPropertyType());

    输出:

      

           

  • 相关阅读:
    测试72.思维好题
    pbds:STL平衡树
    测试69。这场因为轻视少了很多分。
    C++ 中的四种类型转换
    C++ 中的static关键字
    codeforces 1269 E K Integers
    P4556 [Vani有约会]雨天的尾巴 (线段树合并)
    P3521 [POI2011]ROT-Tree Rotations (线段树合并)
    codeforces 600E E. Lomsat gelral (线段树合并)
    线段树合并的一些题
  • 原文地址:https://www.cnblogs.com/fjdingsd/p/5272113.html
Copyright © 2020-2023  润新知