參考文獻3 指出有兩個方法可以解決這個問題。一是被裝載的模塊是虛擬機的主類庫加載器已經加載的某個類庫的派生類庫(subclass),一是被加載的模塊實現某個已經被系統虛擬機的主類庫加載器加載的接口(interface)。 在瀏覽器中通常都使用了第一種方法,譬如說所有的applet都是java.applet.Applet的派生類庫,因此在所有的applet源代碼中都有類似于public class MyClass extends Applet 的聲明。在這里我們采用參考文獻3 中介紹的第二種方法,也就是被加載的新模塊實現某個預先設計好的接口。
聲明接口UpdatableModule如下: public interface UpdatableModule { void start(String RunTimeParam) }
由于這個接口在設計時刻已經存在,它可以被虛擬機的主類庫加載器和將要被加載的新功能模塊所調用。新功能模塊所需要做的,只是實現這個接口中的方法,例如: public class NewModule_1 implements UpdatableModule { void start(String RunTimeParam) { System.out. } } public class NewModule_2 implements UpdatableModule { void start(String RunTimeParam) { System.out.println("This is new module 2."); } }
在運行時刻,主程序需要從外部獲得新的功能模塊名,利用用戶自定義的類庫加載器加載新的功能模塊,生成一個新的功能模塊對象,然后通過事先定義好的接口調用新的功能模塊中的方法。例如: public class Test { public static void main(String[] args) { SimpleClassLoader scl = new SimpleClassLoader(); String RunTimeModule; Object o; Class c; RunTimeModule = args[0]; c = scl.loadClass(RunTimeModule); o = c.newInstance(); ((UpdatableModule) o).start("No parameter needed."); } }
示范程序 下面我們介紹一個簡單的數據采集與處理程序。該程序采集當前的系統時間并按照一定的格式輸出到標準輸出設備,其中的數據處理模塊(即數據輸出模塊)可以在運行時刻被更新。該程序包括如下功能模塊: DataBuffer---------數據緩沖區 DataCollector------數據采集模塊 DataProcessor------數據處理模塊接口 PrintData_1--------數據輸出模塊,實現數據處理模塊DataProcessor的接口 PrintData_2--------數據輸出模塊,實現數據處理模塊DataProcessor的接口 TestGUI------------測試圖形界面 數據緩沖區DataBuffer存放數據采集模塊DataCollector 所采集的數據,它提供了更新數據和查詢數據的方法。 public class DataBuffer { private String data;
// 更新數據的方法
public synchronized void UpdateData(String s) { data = s; notifyAll(); }