感覺在設計模式當中,很多很多地方都要用到反射。尤其是從設定檔當中讀取資訊,並使用這個資訊來動態載入。反射的應用特別常見,這裡再一次的討論反射和相關概念。
ClassLoader的類載入機制:
l Java當中的類不是一次性都載入到記憶體當中
l 而是需要的時候才動態載入到記憶體當中,也就是說是運行期間的動態載入。
l 靜態語句是在載入後執行一次,而且執行一次
l Dynamic語句塊每次new新的對象都會執行。
Java當中的ClassLoader很多:
Bootstrap class loader 最頂層的CL,負責管理class。可能是用c或者是彙編寫的。不允許使用者訪問。
Extension class loader
Application class loader
Other class loaders
n Secure class loader
n URL clas loader
感覺還是在設定檔當中讀取類的名字,反射最常見。
1. 屬性檔案的位置:
不要寫死在某個目錄當中
也不要用相對路徑(考慮放在jar包當中的情況)
最常用的位置,放到classpath裡面。就可以被properties訪問到了。在eclipse當中體現為放在src目錄下。Src編譯好的東西,會被eclipse放到當前項目的classpath當中,所以能被properties訪問了。
2. 屬性檔案的內容:
observers=com.bjsxt.dp.observer.Dad,com.bjsxt.dp.observer.GrandFather,com.bjsxt.dp.observer.Dog
observers為鍵。
com.bjsxt.dp.observer.Dad,com.bjsxt.dp.observer.GrandFather,com.bjsxt.dp.observer.Dog為值,中間用逗號隔開。
3. 使用者當中,通過一個PropertyMgr的輔助類,來得到設定檔當中的資訊。
class PropertyMgr {
//使用系統對象,properties,要求設定檔放在classpath裡面
privatestatic Propertiesprops
=new Properties();
static {
try {
//通過properties找到設定檔
//注意這裡必須使用try catch。
props.load(Test.class.getClassLoader().getResourceAsStream("com/bjsxt/dp/observer/observer.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}
//通過getProperty來擷取屬性的值。就是在設定檔,後面的部分
publicstatic StringgetProperty(String key) {
returnprops.getProperty(key);
}
}
事實上,得到了屬性的值還沒有完成,得到的是一個字串。需要繼續通過string的split方法來得到每一個類。然後再產生這些類的對象們。
//對properties得到的字串,用split來處理
String[] observers = PropertyMgr.getProperty("observers").split(",");
//對每個類,都產生對象,注意這裡要try catch
for(String s : observers) {
try {
c.addWakenUpListener((WakenUpListener)(Class.forName(s).newInstance()));
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}