39

我从Class.getResource() 和 ClassLoader.getResource() 有什么区别? 从自己的代码中,

getClass().getResource("/path/image.png")

等同于

getClass().getClassLoader().getResource("path/image.png")

发布无法读取 jar 文件中的图像显示使用问题

getClass().getClassLoader().getResource("path/image.png")

在可执行 jar 文件中返回 null,而

getClass().getResource("/path/image.png")

返回正确的 URL。

Since Class.getResource()代表ClassLoader.getResource()在删除前导斜杠后,我希望这些调用是相同的,但显然在这种情况下它们不是。即使将一个特殊的类加载器附加到特定类,每次调用它仍然应该是相同的,再次导致相同的行为。

所以,问题是:是否有任何明显的情况下,以下代码在第一次调用时返回 null 而在第二次调用时返回正确的 URL?

package com.example;

import java.net.URL;

public class ResourceTest {

   public void run() {
      URL iconUrl1 = getClass().getClassLoader().getResource("path/image.png");
      System.out.println("ClassLoader.getResource(\"path/image.png\"): " + iconUrl1);

      URL iconUrl2 = getClass().getResource("/path/image.png");
      System.out.println("Class.getResource(\"/path/image.png\"): " + iconUrl2);
   }

   public static void main(String[] args) {
      ResourceTest app = new ResourceTest();
      app.run();
   }
}
4

1 回答 1

43

我以为这个问题已经被问及回答了!

getClass().getResource()相对于 .class 文件进行 getClass().getClassLoader().getResource()搜索,同时相对于类路径根进行搜索。

如果这里有 SSCCE,我不明白为什么它没有

1) 在 .jar 中显示目录组织,然后...

2)考虑包装

问:Class.getResource() 和 ClassLoader.getResource() 之间的区别是什么?(以及它引用的链接)?

==================================================== ========================

我仍然不确定什么不清楚,但这个例子可能会有所帮助:

/*
  SAMPLE OUTPUT:
  ClassLoader.getResource(/subdir/readme.txt): NULL
  Class.getResource(/subdir/readme.txt): SUCCESS

  ClassLoader.getResource(subdir/readme.txt): SUCCESS
  Class.getResource(subdir/readme.txt): NULL
 */
package com.so.resourcetest;

import java.net.URL;

public class ResourceTest {

    public static void main(String[] args) {
        ResourceTest app = new ResourceTest ();
    }

    public ResourceTest () {
        doClassLoaderGetResource ("/subdir/readme.txt");
        doClassGetResource ("/subdir/readme.txt");
        doClassLoaderGetResource ("subdir/readme.txt");
        doClassGetResource ("subdir/readme.txt");
    }

    private void doClassLoaderGetResource (String sPath) {
        URL url  = getClass().getClassLoader().getResource(sPath);
        if (url == null)
            System.out.println("ClassLoader.getResource(" + sPath + "): NULL");
        else
            System.out.println("ClassLoader.getResource(" + sPath + "): SUCCESS");
    }

    private void doClassGetResource (String sPath) {
        URL url  = getClass().getResource(sPath);
        if (url == null)
            System.out.println("Class.getResource(" + sPath + "): NULL");
        else
            System.out.println("Class.getResource(" + sPath + "): SUCCESS");
    }
}

这是相应的目录树。它恰好是一个 Eclipse 项目,但无论是 Eclipse、Netbeans ... 还是 .jar 文件,目录都是相同的:

C:.
├───.settings
├───bin
│   ├───com
│   │   └───so
│   │       └───resourcetest
│   └───subdir
└───src
    ├───com
    │   └───so
    │       └───resourcetest
    └───subdir

正在打开的文件是“subdir/readme.txt”


附录 11/9/12:

你好 -

我从github逐字复制了您的代码,重新编译并重新运行:

ClassLoader.getResource(/subdir/readme.txt): NULL
Class.getResource(/subdir/readme.txt): SUCCESS
ClassLoader.getResource(subdir/readme.txt): SUCCESS
Class.getResource(subdir/readme.txt): NULL

如果这不是你得到的输出......我很困惑。

不管它值多少钱,我都在跑:

  • Eclipse Indigo(没关系)

  • 在 IDE 内部运行(无论是文件系统还是 .jar,在 IDE 内部还是外部都无关紧要)

  • 我的 JRE 是 1.6(如果有的话,这可能是大问题)

抱歉,我们无法解决我认为很简单的问题:(


附录 11/21/12(安德烈亚斯):

由于最近没有关于这个问题的活动,我想总结一下我们的发现:

  • 根据我们的普遍理解,上述问题的答案是:“不,不可能Class.getResource("/path/image.png")返回有效的 URL,而ClassLoader.getResource("path/image.png")返回 null”
    • 我们完全清楚 ClassLoader.getResource() 和 Class.getResource() 之间的区别
    • 我们的样本输出匹配,“SUCCESS”和“null”
    • 样本输出符合我们的预期
    • 结论:要么我们监督了某些事情,要么某些不同的事情导致链接问题中描述的“解决方案”起作用。我认为我们目前无法证明其中之一。
于 2012-11-08T15:42:19.520 回答