內省(一)之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());

輸出:

  

 

 

 

 

       

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM