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

Why did this code stop working after I switched machines?

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

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 运行安装它。但是我最近买了一台新笔记本电脑,当我尝试在新机器上 运行 时,jar 不会 运行; stream 总是变成 null。但是,当我从 Eclipse 内部 运行ning 时,不会出现此问题。

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

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

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

那么,这两种加载资源的方式有什么区别呢? (我听说它是​​关于 ClassLoaders 的,但我记不起确切的词了。)为什么切换到新机器会破坏第一台机器?即使是第二个,我做对了吗?

MyClass.class returns java.lang.Class 代表 class MyClass 的实例。在 returns 上调用 .getClass 表示 java.lang.Class 本身的 Class 实例,并在 THAT 上调用 getResourceAsStream 将尝试在 [=23= 中定位资源](java.lang.Class 居住的地方)。一般来说,不是你想要的。换句话说,您的第一个示例与 java.lang.Class.class.getResourceAsStream(...).

相同

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

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