为什么这台代码在我切换机器后停止工作?

问题描述 投票:1回答:1

我使用Eclipse开发了一个Java项目,需要加载一些图像并显示它们。起初,我这样加载它们:

InputStream stream = MyClass.class.getClass().getResourceAsStream("/resources/ui/icons/" + name);
Image img = ImageIO.read(stream).getScaledInstance(size.width, size.height, Image.SCALE_SMOOTH);

无论我是从Eclipse运行还是从可执行jar运行它,这都运行良好。但是我最近买了一台新笔记本电脑,当我试图在新机器上运行它时,罐子就不会运行了; stream总是证明是null。但是,当我从Eclipse内部运行时,不会发生此问题。

最后,经过一些实验,我改变了代码,直接在getResourceAsStream()上调用MyClass.class而不调用getClass()

InputStream stream = MyClass.class.getResourceAsStream("/resources/ui/icons/" + name);
Image img = ImageIO.read(stream).getScaledInstance(size.width, size.height, Image.SCALE_SMOOTH);

出于某种原因,它有效。我的新笔记本电脑具有与旧笔记本电脑相同的操作系统(Windows 10)和其他设置,但它运行Eclipse Photon而不是Oxygen。

那么,两种加载资源的方式有什么区别? (我听说这是关于ClassLoaders的东西,但我记不起确切的话。)为什么切换到新机器会打破第一个?即使是第二个,我正确地做到了吗?

java jar resources classloader resource-loading
1个回答
2
投票

MyClass.class返回表示类MyClass的java.lang.Class实例。调用.getClass返回表示java.lang.Class本身的Class实例,并在THAT上调用getResourceAsStream将尝试在java.base中找到资源(java.lang.Class所在的位置)。一般来说,不是你想要的。换句话说,你的第一个例子与java.lang.Class.class.getResourceAsStream(...)相同。

第二个例子是正确的方法。

第一件事在一些地方起作用的原因是因为它完全取决于如何在Java SE 8及更早版本中指定Class.getResourceXXX。 Java SE 9中的规范已更改,以处理Class是命名模块的类。

© www.soinside.com 2019 - 2024. All rights reserved.