获取 JAVA 中动态加载 Class 的 .class 文件的路径

Getting the path to a .class file of a dynamically loaded Class in JAVA

我希望实例化并映射我的 class 路径中给定类型的所有 classes。

我已经使用 Reflections 库完成了扫描,并获得了已加载的 classes 的列表。

然后,当我映射它们时,我正在检查冲突(关键是简单的 class 名称)。

发生这种情况时,我想抛出一个异常,指出冲突的 classes 的完全限定名称,以及它们从中加载的路径(例如 JARs 每个人都可能找到)。

我知道也可以从内存加载 class,但假设我是从磁盘上的 JAR 加载它,我想知道是否有任何方法可以获取该路径...

参见下面的代码片段:

if (isConflictingFactoryRegistered(key, myFactory)) {
        Class<? extends MyFactory> class1 = factoryMap.get(key).getClass();
        Class<? extends MyFactory> class2 = myFactory.getClass();
        try {
            throw new RuntimeException("Found two conflicting factories for " + key
                    + ": 1. " + class1 + " in " + getClass().getResource(class1.getSimpleName()+".class").toURI() +
                       " 2. " + class2 + " in " + getClass().getResource(class2.getSimpleName()+".class").toURI());
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    } else {
        factoryMap.put(myFactory.getName(), myFactory);
    }

此代码确实可以编译 - 但无法运行; getClass().getResource(class1.getSimpleName()+".class") returns 空。如何获得 .class 的路径?

我建议你更换

throw new RuntimeException("Found two conflicting factories for " + key
  + ": 1. " + class1 + " in " + getClass().getResource(class1.getSimpleName()+".class").toURI() +
  " 2. " + class2 + " in " + getClass().getResource(class2.getSimpleName()+".class").toURI());

throw new RuntimeException("Found two conflicting factories for " + key
  + ": 1. " + class1 + " in " + class1.getResource(class1.getSimpleName()+".class").toURI() + 
 " 2. " + class2 + " in " + class2.getResource(class2.getSimpleName()+".class").toURI());

这适用于我机器上的任意两个 classes。

一般来说,我认为 Class.getResource() 只能找到加载特定 class 的同一类加载器可用的资源 - 根据 the API

This method delegates to this object's class loader. If this object was loaded by the bootstrap class loader, the method delegates to ClassLoader.getSystemResource(java.lang.String).

我怀疑如果您查看示例中的 getClass().getClassLoader()class1.getClassLoader(),您可能会发现它们是不同的。