在Java中加载资源的首选方式

我想知道在Java中加载资源的最佳方式:

  • this.getClass().getResource() (or getResourceAsStream())
  • Thread.currentThread().getContextClassLoader().getResource(name)
  • System.class.getResource(name)

根据你想要的来制定解决scheme…

getResource / getResourceAsStream()会从调用的类中获得两件事…

  1. 类加载器
  2. 起始位置

所以,如果你这样做

 this.getClass().getResource("foo.txt"); 

它会尝试从“this”类和“this”类的类加载器加载foo.txt。 如果你在前面放一个“/”,那么你完全参考了资源。

 this.getClass().getResource("/x/y/z/foo.txt") 

将从“this”的类加载器和xyz包(它将需要与该包中的类位于相同的目录中)加载资源。

 Thread.currentThread().getContextClassLoader().getResource(name) 

将使用上下文类加载器加载,但不会根据任何包来parsing名称(它必须被绝对引用)

 System.class.getResource(name) 

将使用系统类加载器来加载资源(它也必须被绝对引用,因为你不能把任何东西放到java.lang包(System的包)中。

只要看看源代码。 还指出getResourceAsStream只是从getResource返回的URL上调用“openStream”并返回该值。

那么,如果你真的在派生类中,这部分取决于你想要发生什么。

例如,假设SuperClass在A.jar中, SubClass在B.jar中,并且你正在SuperClass声明的一个实例方法中执行代码,但是这里指的是一个SubClass的实例。 如果使用this.getClass().getResource() ,它将在B.jar中看起来相对于SubClass 。 我怀疑这通常不是什么要求。

就我个人而言,我可能会最经常使用Foo.class.getResourceAsStream(name) – 如果您已经知道您所使用的资源的名称,并且您确定它与Foo相关的位置,那么这是最可靠的方法做IMO。

当然,有些时候这也不是你想要的:根据其优点判断每个案例。 这只是“我知道这个资源与这个课程捆绑在一起”是我遇到的最常见的一个。

我search了三个地方,如下所示。 评论欢迎。

 public URL getResource(String resource){ URL url ; //Try with the Thread Context Loader. ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); if(classLoader != null){ url = classLoader.getResource(resource); if(url != null){ return url; } } //Let's now try with the classloader that loaded this class. classLoader = Loader.class.getClassLoader(); if(classLoader != null){ url = classLoader.getResource(resource); if(url != null){ return url; } } //Last ditch attempt. Get the resource from the classpath. return ClassLoader.getSystemResource(resource); } 

我知道真的很晚了,但我只是想分享最后的帮助。 它也会从文件系统的绝对path(不仅是类path)加载资源/文件。

 public class ResourceLoader { public static URL getResource(String resource) { final List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(); classLoaders.add(Thread.currentThread().getContextClassLoader()); classLoaders.add(ResourceLoader.class.getClassLoader()); for (ClassLoader classLoader : classLoaders) { final URL url = getResourceWith(classLoader, resource); if (url != null) { return url; } } final URL systemResource = ClassLoader.getSystemResource(resource); if (systemResource != null) { return systemResource; } else { try { return new File(resource).toURI().toURL(); } catch (MalformedURLException e) { return null; } } } private static URL getResourceWith(ClassLoader classLoader, String resource) { if (classLoader != null) { return classLoader.getResource(resource); } return null; } } 

我尝试了很多上面提到的方法和function,但是他们在我的项目中没有工作。 无论如何,我已经find解决办法,这里是:

 try { InputStream path = this.getClass().getClassLoader().getResourceAsStream("img/left-hand.png"); img = ImageIO.read(path); } catch (IOException e) { e.printStackTrace(); }