Почему этот код перестал работать после того, как я переключил машины?

Я работал над проектом на 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. Но недавно я получил новый ноутбук, и когда я попытался запустить его на новой машине, банка не работала; 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) и другие настройки, что и старый, но вместо Oxygen работает Eclipse Photon.

Итак, в чем разница между двумя способами загрузки ресурсов? (Я слышал, что это что-то о ClassLoaders, но я не могу вспомнить точные слова.) Почему переключение на новую машину сломало первую? И даже со вторым, я делаю это правильно?

1 ответ

Решение

MyClass.class возвращает экземпляр java.lang.Class, представляющий класс MyClass, Вызов.getClass для этого возвращает экземпляр класса, представляющий java.lang.Class сам и зовет getResourceAsStream на это будет пытаться найти ресурс в java.base (где java.lang.Class жизни). В общем, не то, что вы хотите. Другими словами, ваш первый пример такой же, как java.lang.Class.class.getResourceAsStream(...),

Второй пример - правильный способ сделать это.

Причина, по которой первая вещь работает в нескольких местах, заключается в том, что все зависит от того, как был указан Class.getResourceXXX в Java SE 8 и более ранних версиях. Спецификация изменена в Java SE 9 для работы с классами, где Class является именованным модулем.

Другие вопросы по тегам