[英]Preferred way of loading resources in Java
我想知道在 Java 中加载资源的最佳方式:
this.getClass().getResource() (or getResourceAsStream())
,Thread.currentThread().getContextClassLoader().getResource(name)
,System.class.getResource(name)
。根据您的需要制定解决方案...
getResource
/ getResourceAsStream()
将从它被调用的类中获得两件事......
所以如果你这样做
this.getClass().getResource("foo.txt");
它将尝试从与“this”类相同的包中加载 foo.txt,并使用“this”类的类加载器。 如果您在前面放了一个“/”,那么您绝对是在引用资源。
this.getClass().getResource("/x/y/z/foo.txt")
将从“this”的类加载器和 xyz 包中加载资源(它需要与该包中的类位于同一目录中)。
Thread.currentThread().getContextClassLoader().getResource(name)
将使用上下文类加载器加载,但不会根据任何包解析名称(必须绝对引用)
System.class.getResource(name)
将使用系统类加载器加载资源(它也必须被绝对引用,因为您将无法将任何内容放入 java.lang 包(系统包)。
只需看一下来源。 还表示 getResourceAsStream 只是在从 getResource 返回的 URL 上调用“openStream”并返回它。
好吧,如果您实际上在派生类中,这部分取决于您想要发生什么。
例如,假设SuperClass
在 A.jar 中,而SubClass
在 B.jar 中,并且您正在SuperClass
声明的实例方法中执行代码,但是this
指的是SubClass
的实例。 如果您使用this.getClass().getResource()
它将看起来相对于 B.jar 中的SubClass
。 我怀疑这通常不是必需的。
就我个人而言,我可能最常使用Foo.class.getResourceAsStream(name)
- 如果您已经知道您要Foo.class.getResourceAsStream(name)
的资源的名称,并且您确定它相对于Foo
,那么这是最可靠的方法这样做海事组织。
当然,有时这也不是您想要的:根据每个案件的优点来判断。 只是“我知道此资源与此类捆绑在一起”是我遇到的最常见的问题。
我搜索三个地方,如下所示。 欢迎评论。
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);
}
我知道另一个答案真的很晚了,但我只是想分享最后对我有帮助的东西。 它还将从文件系统的绝对路径(不仅是类路径)加载资源/文件。
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;
}
}
我尝试了很多上面建议的方法和功能,但它们在我的项目中不起作用。 无论如何,我找到了解决方案,这里是:
try {
InputStream path = this.getClass().getClassLoader().getResourceAsStream("img/left-hand.png");
img = ImageIO.read(path);
} catch (IOException e) {
e.printStackTrace();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.