黑馬程式設計師 Java高新技術--反射和內省
1.框架與框架要解決的核心問題:
比如:我做房子賣給使用者住,由使用者自己安裝門窗和空調,我做的房子就是框架,使用者需要使用我的框架,把門窗插入進我提供的框架中。框架和工具類有區別,工具類被使用者的類呼叫,而框架則是呼叫使用者提供的類。
2.框架要解決的核心問題:
我在寫框架(房子)時,你這個使用者可能還在上小學,還不會寫程式呢。我寫的框架程式怎樣能呼叫到你以後寫的類(門窗)呢?
因為在寫程式時無法知道要被呼叫的類名,所以,在程式中無法直接new某個類的例項物件了,而要用反射方式來做。
3、簡單框架程式的步驟:
1)右擊專案名-->File-->命名,寫入鍵值對:className=java.util.ArrayList,等號右邊的可以自己定義集合的名稱,即使用者可以對此記事本修改成自己的類名。
2)程式碼實現,載入此檔案:
①將檔案讀取到讀取流中,一定要用完整的路徑,可以使用getRealPath()方法獲取路徑名,再加上自己定義的資料夾名。
②用Properties類的load()方法將流載入經記憶體,即提取檔案中的資訊。
③關閉流:關閉的是讀取流,因為流中的資料已經載入進記憶體。
3)通過getProperty()方法獲取類名屬性,將傳入的類名賦值給指定變數。
4)用反射的方式,建立物件newInstance()
5)進行相關的具體操作。
package javaenhance; import java.io.FileInputStream; import java.io.InputStream; import java.util.Collection; import java.util.Properties; public class ReflectTest4 { /** * @param args */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub //InputStream is = new FileInputStream("cofig.properties"); //InputStream is=ReflectTest4.class.getClassLoader().getResourceAsStream("javaenhance/cofig.properties"); InputStream is=ReflectTest4.class.getResourceAsStream("resources/cofig.properties"); Properties props = new Properties(); props.load(is); is.close(); String className = props.getProperty("className"); Collection list = (Collection)Class.forName(className).newInstance(); // Set list = new HashSet(); ReflectPoint rp = new ReflectPoint(3,3); ReflectPoint rp1= new ReflectPoint(5,8); ReflectPoint rp2 = new ReflectPoint(3,3); list.add(rp); list.add(rp1); list.add(rp2); list.add(rp); System.out.println(list.size()); } }
八 由內省引出JavaBean的講解
一. IntroSpector: 主要用於對javabean的操作。
二.什麼是JavaBean?
javaBean是一種特殊的java類,主要用於傳遞資料資訊,這種java類中的方法主要用於訪問私有的欄位,且方法名符合某種命名規則。
三.作用:
如果要在兩個模組之間傳遞多個資訊,可以將這些資訊封裝到一個javaBean中,這種javaBean的例項物件通常被稱之為值物件
這些資訊在類中用私有欄位來儲存,如果讀取或設定這些欄位的值,則需要通過一些相應的方法來訪問。
四.命名規則:
JavaBean的屬性是根據其中的setter和getter方法來確定的,而不是根據其中的成員變數。如果方法名為setId,中文意思
即為設定id,至於你把它存到哪個變數上,用管嗎?如果方法名為getId中文意思即為獲取id,至於你從哪個變數上取,用管嗎?
去掉set字首,剩餘部分就是屬性名,如果剩餘部分的第二個字母是小寫的,則把剩餘部分的首字母改成小的。
五.好處:
JDK提供了對JavaBean進行操作的一些API,這套API就稱為內省。如果要你自己去通過getX方法來訪問私有的x,怎麼做,有一定難度吧?用內省這套API操作javaBean比用普通類的方式更方便。
PropertyDescriptor類:PropertyDescriptor 描述 Java Bean 通過一對儲存器方法匯出的一個屬性。
構造方法:
public PropertyDescriptor(String propertyName,Class<?> beanClass)
引數:
propertyName- 屬性的程式設計名稱。
beanClass- 目標 bean 的 Class 物件。
特有方法:
Method getReadMethod(); :獲得應該用於讀取屬性值的方法。
Method getWriteMethod(); :獲得應該用於寫入屬性值的方法。
下面對JavaBean進行簡單的內省操作。
思路:
1.建立 PropertyDescriptor的例項物件。傳入要操作的屬性值,和目標bean的Class物件。
2.通過getReadMethod()或getWriteMethod()方法獲取到讀取屬性值得方法。
3.再通過Method的方法invoke().獲得屬性值。
六.對JavaBean的複雜內省操作。
思路:
1.通過Introspector的方法getBeanInfo(Class<?> beanClass).
2.在Java Bean上進行內省,瞭解其所有屬性,公開的方法和事件。
3.在通過得到的benaninfo類的getPropertyDescriptors()方法獲的PropertyDescriptor陣列。
最後通過增強for迴圈獲得自己想要獲取的屬性值對應的PropertyDescriptor類。