內省機制(操作javaBean的資訊)
----是不是聯想到了反射機制了哈,這兩者有什麼區別呢?
1、內省機制和反射機制的聯絡
■ 其實內省機制也是通過反射來實現的,而反射是對一切類都適合去動態獲取類的資訊,而內省機制是sun公司針對特殊的類---javaBean推出的技術。內省機制就是用來獲取javabean的資訊的。
2、什麼是javaBean?
■ 比較官方的描述:javaBean 是一種java 語言寫成的可重用的元件(類)。
■ 簡單理解:就是一種特殊類,遵循特定的規範,遵循的規範如下:
-
必須使用 public 修飾(javabean)類
-
(javabean)類必須有公共無參構造器
-
包含有屬性的操作手段(獲取屬性值或給屬性賦值---getter/setter)
■ javaBean 可以很複雜,也可以很簡單。
-
javabean 可以有的資訊(不是必備):方法Method、事件event、屬性property
-
補充一下屬性property:表示狀態,不是欄位,是欄位的操作方法getter、setter方法決定的,判斷屬性看getter/setter
□ 複雜的javabean擁有了事件、屬性、方法,例如UI(button、panel、window類);
□ 簡單的javabean,最簡單最常用的有實體類domain-包含了屬性和操作屬性的getter、setter方法,還有dao、service元件,封裝資料,運算元據庫,邏輯運算等。
3、內省機制(自省機制)的作用:就是用來檢視和操作javaBean的資訊(屬性、方法、事件)
--------一般常用來操作簡單的javaBean(domain類)的屬性。
(1)獲取屬性名或屬性型別
(2)設定屬性值或獲取屬性值-通過反射呼叫setter或getter方法(setter/getter)
4、內省機制的核心類---Introspector
-
注意核心類在哪個包
,例如反射-Class在lang包裡,內省的Introspector在beans包裡 -
抓住核心類Introspector(學習的突破口),順騰摸瓜,例如反射抓住核心類Class,然後順藤摸瓜,獲得構造器Constructor、方法Method;
-
我們知道javaBean可以具有屬性、事件、方法,而操作javabean的內省機制,它的核心類Introspector就是操作javaBean的屬性、事件、方法。
5、Introspector
(核心類、學習內省機制的突破口、學習操作javaBean的學習入口)---操作javaBean
-
第一步就是先得到該javaBean:【在突破口中:
得到javaBean的描述物件BeanInfo物件
】- 方法getBeanInfo的引數是該javaBean的位元組碼,結果是得到javaBean的資訊---BeanInfo物件(javaBean的描述物件)
-
第二個突破口擁有javaBean的一切的BeanInfo:【在突破口中:
得到javaBean的屬性描述器PropertyDescriptor
】- 方法getPropertyDescriptors(),結果是得到javaBean的屬性資訊---PropertyDescriptor屬性陣列物件(javaBean的屬性描述器物件)
-
第三個突破口擁有javaBean的屬性的一切的PropertyDescriptor:【在突破口中:
得到關於屬性的操作
】- 屬性描述器是陣列----遍歷
6、內省機制操作javaBean的屬性程式碼如下:
@Test
public void testIntrospector() throws Exception {
//1、通過突破口(核心類Introspector)獲取javaBean描述物件BeanInfo
BeanInfo beanInfo = Introspector.getBeanInfo(Person.class,Object.class);
//2、獲取javaBean中的屬性描述器
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
//建立一個Person物件
Person person = new Person();
for (PropertyDescriptor pd : pds) {//遍歷陣列描述器陣列
//3-1、獲取當前的屬性的屬性名
System.out.println("當前屬性的屬性名是:" +pd.getName());
System.out.println("當前屬性的getter方法是:" +pd.getReadMethod());
System.out.println("當前屬性的setter方法是:" +pd.getWriteMethod());
if("name".equals(pd.getName())) {//若當前屬性名是name【不能直接使用setName方法,因為反射的時候並不知道是哪個具體的方法】
Method setter = pd.getWriteMethod();//3-2、獲取setter方法
setter.invoke(person, "shan");//設定當前person物件的name值為shan
}
}
}