1. 程式人生 > >黑馬程式設計師 Java高新技術--反射和內省

黑馬程式設計師 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類。