在 JDBC 開發中,Class.forName() 是載入資料庫驅動程式的標準寫法。但當遇到 XML 動態解析分派場景時,開發者常面臨一個棘手問題:如何將儲存為字串的類別名稱實例化為真正的 Class 物件?本文透過一個完整的動態載入器範例,詳細解析 Class.forName() 的進階應用技巧。
以下程式碼展示如何根據命令列參數動態載入類別並呼叫其 main 方法:
public class DynamicLoader {
public static void main(String args[]) throws Exception {
// 根據第一個參數動態載入類別
Class toRun = Class.forName(args[0]);
// 處理剩餘參數
String[] newArgs = scrubArgs(args);
// 尋找並呼叫目標類別的 main 方法
Method mainMethod = findMain(toRun);
mainMethod.invoke(null, new Object[]{newArgs});
}
// 移除第一個參數(類別名),並將其餘參數轉為小寫
private static String[] scrubArgs(String[] args) {
String[] toReturn = new String[args.length - 1];
for (int i = 1; i < args.length; i++) {
toReturn[i - 1] = args[i].toLowerCase();
}
return toReturn;
}
// 透過反射尋找 public static void main(String[]) 方法
private static Method findMain(Class clazz) throws Exception {
Method[] methods = clazz.getMethods();
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equals("main")) {
return methods[i];
}
}
return null;
}
}
編寫一個簡單的測試類別,接收並印出傳入的參數:
public class Echoit {
public static void main(String args[]) {
for (int i = 0; i < args.length; i++) {
System.out.println("Echo arg " + i + " = " + args[i]);
}
}
}
DynamicLoader.class 與 Echoit.classjava DynamicLoader Echoit ONE TWO THREE執行結果將顯示:
Echo arg 0 = one
Echo arg 1 = two
Echo arg 2 = three
Class.forName(String className) 會根據完整類別名稱(含套件路徑)載入對應的 Class 物件,並執行該類別的靜態初始化區塊。這正是 JDBC 載入驅動程式的核心原理——驅動程式在靜態區塊中向 DriverManager 註冊自己。
透過 clazz.getMethods() 取得所有 public 方法,篩選名稱為 "main" 的方法,再使用 Method.invoke() 動態呼叫。注意 main 方法必須宣告為 public static void main(String[]) 才能被正確發現。
命令列參數為字串陣列,第一個元素為目標類別名,其餘為傳遞給目標 main 方法的實際參數。範例中將參數統一轉為小寫展示字串處理彈性。
findMain() 將回傳 null 導致 NullPointerException掌握 Class.forName() 搭配反射 API 的動態載入技術,能大幅提升 Java 應用程式的擴充性與靈活度,是進階 Java 開發者的必備技能。