類別載入器按順序掃描 CLASSPATH,第一個同名類別即被載入,後續同名類別被「隱藏」。專案增長導致 CLASSPATH 膨脹、版本衝突、重複項目時,極難判斷實際載入的是哪個 JAR/目錄。
Unix which 指令:分析 PATH 顯示可執行檔實際路徑。JWhich 移植此概念至 Java 類別載入機制。
> java JWhich com.clarkware.ejb.ShoppingCartBean
Class 'com.clarkware.ejb.ShoppingCartBean' found in
'/home/mclark/classes/com/clarkware/ejb/ShoppingCartBean.class'
> java JWhich javax.servlet.http.HttpServlet
Class 'javax.servlet.http.HttpServlet' found in
'file:/home/mclark/lib/servlet.jar!/javax/servlet/http/HttpServlet.class'
public class JWhich {
public static void which(String className) {
if (!className.startsWith("/")) className = "/" + className;
className = className.replace('.', '/') + ".class";
// 向「載入 JWhich 自身的 ClassLoader」查詢資源
URL classUrl = new JWhich().getClass().getResource(className);
if (classUrl != null) {
System.out.println("Class '" + className + "' found in '" + classUrl.getFile() + "'");
} else {
System.out.println("Class '" + className + "' not found in '" +
System.getProperty("java.class.path") + "'");
}
}
public static void main(String[] args) {
if (args.length > 0) which(args[0]);
else System.err.println("Usage: java JWhich ");
}
}
Class.getResource() 委派給載入該類別的 ClassLoader,自動遵循雙親委派模型,完整模擬實際載入邏輯。. → /、前綴 / 表示絕對路徑匹配、附加 .class。NoClassDefFoundError、LinkageError、版本不一致java -verbose:class:JVM 參數,啟動時印出所有載入類別來源sc、classloader 指令JWhich 雖簡單,卻直擊 CLASSPATH 核心痛點,是理解類別載入機制的最佳教學工具之一。