天天看點

黑馬程式員---内省和JavaBean

------- android教育訓練、java教育訓練、期待與您交流! ----------

1、為什麼要學内省(Introspector)?

        開發架構時,經常需要使用Java對象的屬性來封裝程式的資料,每次都使用反射技術完成此類操作過于麻煩,是以sun公司開發了一套API,專門用于操作java對象的屬性,就是内省。

2、這類Java對象有什麼特點?

        是一種特殊的Java類叫做JavaBean類,主要用于傳遞資料資訊,這種java類中的方法主要用于通路私有的字段,且方法名符合某種命名規則。如果要在兩個子產品之間傳遞多個資訊,可以将這些資訊封裝到一個JavaBean中,這種JavaBean的執行個體對象通常稱之為值對象(Value Object,簡稱VO)。這些資訊在類中用私有字段來存儲,如果讀取或設定這些字段的值,則需要通過一些相應的方法來通路,JavaBean的屬性是根據其中的setter和getter方法來确定的,而不是根據其中的成員變量。去掉set和get字首,剩餘部分就是屬性名,如果剩餘部分的第二個字母是小寫的,則把剩餘部分的首字母改成小的。

        setId()的屬性名->id

        isLast()的屬性名->last

        setCPU的屬性名是什麼?->CPU

        getUPS的屬性名是什麼->UPS

總之,一個類被當作javaBean使用時,JavaBean的屬性是根據方法名推斷出來的,它根本看不到java類内部的成員變量。

3、JavaBean類的優勢

        提高代碼的可複用性:對于通用的事務處理邏輯,資料庫操作(insert、delete、update、select等)都可以封裝在JavaBean中,通過調用JavaBean的屬性和方法可快速進行程式設計。

4、内省的對JavaBean的操作

        内省通路JavaBean屬性的兩種方式: 

        通過PropertyDescriptor類操作Bean的屬性 

        通過Introspector類獲得Bean對象的 BeanInfo,然後通過 BeanInfo 來擷取屬性的描述器( PropertyDescriptor ),通過這個屬性描述器就可以擷取某個屬性對應的 getter/setter 方法,然後通過反射機制來調用這些方法。

        執行個體如下:

ReflectPoint pt1 = new ReflectPoint(3,5);
        String propertyName = "x";
        Object retVal = getProperty(pt1, propertyName);
        System.out.println(retVal);
        @Test
        public void test() throws Exception{   
             Student stu=new Student();
              // 1、通過Introspector類獲得Bean對象的BeanInfo   
             BeanInfo entity=Introspector.getBeanInfo(Student.class); 
             // 2、然後通過 BeanInfo 來擷取屬性的描述器(PropertyDescriptor)  
             PropertyDescriptor pds[]= entity.getPropertyDescriptors();  
             // 3、通過這個屬性描述器就可以擷取某個屬性對應的getter/setter方法 
             for(PropertyDescriptor pd:pds){     
                  if(pd.equals("age")){ //age是什麼類型?  
                  //擷取屬性的類型     
                  System.out.println(pd.getName()+""+pd.getPropertyType());    
                  Method md=pd.getWriteMethod();     
                  md.invoke(stu, 122); 
                  break;   
                  }   
            }   
           System.out.println(stu.getAge()); 
       }           

5、内省--Beanutils工具包

       Sun公司的内省API過于繁瑣,是以Apache組織結合很多實際開發中的應用場景開發了一套簡單、易用的API操作Bean的屬性——BeanUtils

       使用前提:引入beanutils包和logging包。

       Beanutils工具包的常用類:

       BeanUtils--get屬性時傳回的結果為字元串,set屬性時可以接受任意類型的對象,通常使用字元串。

       PropertyUtils--get屬性時傳回的結果為該屬性本來的類型,set屬性時隻接受該屬性本來的類型。

       執行個體如下:

public void test1()throws Exception{   
         Class cls = Class.forName("cn.itcast.beanutils.Student");   
         Student bean  = (Student)cls.newInstance();  
 
         BeanUtils.setProperty(bean, "name", "zhangxiaoxiang");    
         String name = BeanUtils.getProperty(bean, "name");   
         System.out.println(name); 


         BeanUtils.setProperty(bean, "age", "100");   
         String a = BeanUtils.getProperty(bean, "age");   
         System.out.println(a); 
          
         // birthday是Date類型的,Date類有setTime方法,是以支援級聯操作
         BeanUtils.setProperty(bean, "birthday.time", "1111");
         System.out.println(bean.getAge());  
         System.out.println(bean.getName());
         System.out.println(bean.getBirthday());
         System.out.println(bean.getBirthday().getTime());


         PropertyUtils.setProperty(bean, "age", 101);
         System.out.println(PropertyUtils.getProperty(bean, "age"));  
}