------- 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"));
}