首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 獲取類文件相對路徑的通用方法

     編輯:Java 相關知識

核心工具類

public class ClassPathUtil {
    /**
     * 獲取類的 .class 文件所在路徑(目錄或 JAR 文件路徑)
     */
    public static String getClassPath(Class cls) throws IOException {
        if (cls == null) throw new NullPointerException();
        URL url = getClassLocationURL(cls);
        if (url == null) return null;
        String path = url.getPath();
        if ("jar".equalsIgnoreCase(url.getProtocol())) {
            try {
                path = new URL(path).getPath(); // 去掉 jar: 前綴
            } catch (MalformedURLException ignored) {}
            int idx = path.indexOf("!/");
            if (idx != -1) path = path.substring(0, idx);
        }
        File file = new File(path.replaceAll("%20", " "));
        return file.getCanonicalPath();
    }

    private static URL getClassLocationURL(Class cls) {
        String resource = cls.getName().replace('.', '/') + ".class";
        ProtectionDomain pd = cls.getProtectionDomain();
        if (pd != null) {
            CodeSource cs = pd.getCodeSource();
            if (cs != null) {
                URL loc = cs.getLocation();
                if (loc != null) {
                    if ("file".equals(loc.getProtocol())) {
                        try {
                            if (loc.toExternalForm().endsWith(".jar") || loc.toExternalForm().endsWith(".zip")) {
                                return new URL("jar:" + loc.toExternalForm() + "!/" + resource);
                            } else if (new File(loc.getFile()).isDirectory()) {
                                return new URL(loc, resource);
                            }
                        } catch (MalformedURLException ignored) {}
                    }
                }
            }
        }
        ClassLoader cl = cls.getClassLoader();
        return cl != null ? cl.getResource(resource) : ClassLoader.getSystemResource(resource);
    }
}

使用示例

// 獲取當前類所在路徑
String path = ClassPathUtil.getClassPath(MyClass.class);
System.out.println(path);
// 輸出示例: /home/user/project/target/classes 或 /home/user/project/lib/mylib.jar

// 獲取 JDK 類路徑
System.out.println(ClassPathUtil.getClassPath(String.class));
// 輸出: /usr/lib/jvm/java-11-openjdk/lib/modules  (JDK 9+ 模塊系統)

應用場景

  • 讀取同目錄下的配置文件(new File(path, "config.properties"))。
  • 掃描包下所有類文件(配合 Files.walk 或 JarFile API)。
  • 插件系統動態加載外部 JAR 並定位資源。

注意事項

  • JDK 9+ 模塊系統下,String.class 等核心類位於 jrt:/ 文件系統,getPath() 返回 /modules/java.base,實際無法直接作為文件訪問。
  • URL 路徑含空格會被編碼為 %20,需解碼後構造 File。
  • 多類加載器環境(OSGi, Spring Boot FatJar, Tomcat)下,getClassLoader() 返回的加載器可能不同,優先使用 ProtectionDomain 獲取 CodeSource。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved