天天看點

Java 動态加載

什麼是Java 動态加載

動态加載是指在程式運作階段,将寫好的類通過類裝載器動态的裝載這個類到JVM中,然後再根據這個類内容(引用的包),再去裝載其他的類.

動态加載的作用

  1. 與動态加載所對應的是Java靜态加載,靜态加載的耦合度高,不利于功能擴充,使用動态加載可以不用修改源程式。
  2. 若項目複雜,當添加新功能的時候,靜态加載極易出錯。動态加載可以避免這類問題。

靜态加載執行個體

  1. Comic 類,實體類(entity)
package test.sf.dynamicLoad;
public class Comic {
	public void read() {
		System.out.println("read comic book");
	}
}
           
  1. Animation 類,實體類(entity)
package test.sf.dynamicLoad;

public class Animation {
	public void read() {
		System.out.println("animation");
	}
}
           
  1. 靜态加載
package test.sf.dynamicLoad;
public class Book {
	public static void main(String[] args) {
		if(args.length!=0) {
			if (args[0].equals("Comic")) {
				Comic comic = new Comic();
				comic.read();
			} else if (args[0].equals("Animation")) {
				Animation animation = new Animation();
				animation.read();
			}
		}
	}
}
           

這樣的加載會出現一個問題,如果我需要繼續添加不同種類的書籍,則必須要改動靜态加載類,進而能夠添加不同種類的書籍。

動态加載執行個體

動态加載執行個體主要是修改加載方法。

public class Book {
	public static void main(String[] args) {
		//動态編譯
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
		int status = compiler.run(null, null, null,new String[]{"-d",System.getProperty("user.dir")+"\\target\\classes", System.getProperty("user.dir")+"\\src\\test\\sf\\dynamicLoad1"});
		if (status!=0) {
			System.out.println("fail");
		}
		try {
		File[] files = new File(System.getProperty("user.dir")+"\\src\\test\\sf\\dynamicLoad1").listFiles();
		System.out.println(files.length);
		
		//動态運作
		for(File f:files) {
			if (f.getName().contains("Book")) {
				continue;
			}
			Class clz = Class.forName("test.sf.dynamicLoad1."+f.getName().replace(".java", ""));
			Method method = clz.getDeclaredMethod("read");
			String result = (String)method.invoke(clz.newInstance());
			System.out.println(result);
		}
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
}
           

動态加載需要注意的幾點:

  1. 利用javax中的類 ToolProvider 完成
  2. 需要注意運用JavaCompiler run函數的時候 的參數清單。
  3. 動态加載完成後,可以采用forname的形式進行動态運作,進而調取每一個編譯後的類。
  4. 動态加載時注意判無法加載的情況。