有人知道如何通过编程找到java类加载器实际从哪里加载类吗?

我经常在大型项目中工作,其中类路径非常长,手动搜索实际上不是一个选择。我最近遇到了一个问题,类加载器加载了一个不正确的类版本,因为它位于类路径的两个不同的地方。

那么,如何让类加载器告诉我实际的类文件来自磁盘的哪个位置呢?

编辑:如果类加载器实际上由于版本不匹配(或其他原因)而无法加载类,我们是否可以在它读取文件之前找到它试图读取的文件?


当前回答

通常情况下,我们不会使用硬编码。我们可以先获取className,然后使用ClassLoader获取类URL。

        String className = MyClass.class.getName().replace(".", "/")+".class";
        URL classUrl  = MyClass.class.getClassLoader().getResource(className);
        String fullPath = classUrl==null ? null : classUrl.getPath();

其他回答

getClass().getProtectionDomain().getCodeSource().getLocation();

假设你正在使用一个名为MyClass的类,下面的代码应该可以工作:

MyClass.class.getClassLoader();

能否获得.class文件在磁盘上的位置取决于类加载器本身。例如,如果您正在使用BCEL之类的东西,那么某个类甚至可能没有磁盘上的表示。

通常情况下,我们不会使用硬编码。我们可以先获取className,然后使用ClassLoader获取类URL。

        String className = MyClass.class.getName().replace(".", "/")+".class";
        URL classUrl  = MyClass.class.getClassLoader().getResource(className);
        String fullPath = classUrl==null ? null : classUrl.getPath();

这种方法对文件和jar都有效:

Class clazz = Class.forName(nameOfClassYouWant);

URL resourceUrl = clazz.getResource("/" + clazz.getCanonicalName().replace(".", "/") + ".class");
InputStream classStream = resourceUrl.openStream(); // load the bytecode, if you wish

这是我们使用的:

public static String getClassResource(Class<?> klass) {
  return klass.getClassLoader().getResource(
     klass.getName().replace('.', '/') + ".class").toString();
}

这取决于ClassLoader的实现: .getLocation .getCodeSource .getProtectionDomain getClass () () () ()