В чем разница между Class.getResource () и ClassLoader.getResource ()?

Интересно, какая разница между Class.getResource() и ClassLoader.getResource() ?

edit: Я особенно хочу знать, связано ли какое-либо кеширование на уровне файлов / каталогов. Как в «списках каталогов, хранящихся в версии classа?»

AFAIK следующее должно по существу сделать то же самое, но они не являются:

 getClass().getResource() getClass().getClassLoader().getResource() 

Я обнаружил это при работе с некоторым кодом генерации отчета, который создает новый файл в WEB-INF/classes/ из существующего файла в этом каталоге. При использовании метода из classа я мог найти файлы, которые были там при развертывании, используя getClass().getResource() , но при попытке извлечь вновь созданный файл я получил нулевой объект. Просмотр каталога ясно показывает, что новый файл есть. Имена файлов были добавлены с помощью косой черты, как в «/myFile.txt».

С ClassLoader версия getResource() classа getResource() обнаружила сгенерированный файл. Из этого опыта кажется, что происходит какое-то кэширование списка каталогов. Правильно ли, и если да, то где это документировано?

Из документов API на Class.getResource()

Находит ресурс с заданным именем. Правила поиска ресурсов, связанных с данным classом, реализуются определяющим загрузчиком classа classа. Этот метод делегирует загрузчик classов этого объекта. Если этот объект был загружен загрузчиком classа bootstrap, этот метод делегирует ClassLoader.getSystemResource (java.lang.String).

Для меня это гласит: «Class.getResource действительно вызывает собственный getResource ()» classа loadload. Это будет то же самое, что и getClass().getClassLoader().getResource() . Но, очевидно, нет. Может кто-нибудь, пожалуйста, предоставит мне некоторое освещение в этом вопросе?

Чтобы ответить на вопрос, происходит ли какое-либо кеширование.

Я исследовал этот момент дальше, запустив автономное приложение Java, которое непрерывно загружало файл с диска с помощью метода getResourceAsStream ClassLoader. Я смог отредактировать файл, и изменения были немедленно отображены, т. Е. Файл был перезагружен с диска без кеширования.

Тем не менее: я работаю над проектом с несколькими модулями maven и веб-проектами, которые имеют зависимости друг от друга. Я использую IntelliJ в качестве моей IDE для компиляции и запуска веб-проектов.

Я заметил, что вышеизложенное, похоже, уже не оправдано, причина в том, что файл, который я загружал, теперь запекается в банку и развертывается в зависящем веб-проекте. Я заметил это только после попытки изменить файл в моей целевой папке, но безрезультатно. Это заставило похоже, что происходит кеширование.

Class.getResource может принимать «относительное» имя ресурса, которое обрабатывается относительно пакета classа. В качестве альтернативы вы можете указать «абсолютное» имя ресурса, используя ведущую косую черту. Порты ресурса Resourceload всегда считаются абсолютными.

Итак, в основном эквивалентны:

 foo.bar.Baz.class.getResource("xyz.txt"); foo.bar.Baz.class.getClassLoader().getResource("foo/bar/xyz.txt"); 

И так они (но они отличаются от выше):

 foo.bar.Baz.class.getResource("/data/xyz.txt"); foo.bar.Baz.class.getClassLoader().getResource("data/xyz.txt"); 

Первый вызов выполняет поиск относительно файла .class то время как последний выполняет поиск относительно корня пути к classам.

Чтобы отлаживать такие проблемы, я печатаю URL-адрес:

 System.out.println( getClass().getResource(getClass().getSimpleName() + ".class") ); 

Пришлось посмотреть в спецификации:

  • Class.getResource (ресурс String)

  • КлассLoader.getResource (ресурс String)

Класс getResource () – документация указывает на разницу:

Этот метод делегирует вызов своему загрузчику classов после внесения этих изменений в имя ресурса: если имя ресурса начинается с «/», оно не изменяется; в противном случае имя пакета добавляется к имени ресурса после преобразования «.». на “/”. Если этот объект был загружен загрузчиком загрузки, вызов делегируется ClassLoader.getSystemResource.

Все эти ответы здесь, а также ответы в этом вопросе показывают, что загрузка абсолютных URL-адресов, таких как «/foo/bar.properties», обрабатывалась одинаково с помощью class.getResourceAsStream(String) и class.getClassLoader().getResourceAsStream(String) . Это не так, по крайней мере, не в моей конфигурации Tomcat / версии (в настоящее время 7.0.40).

 MyClass.class.getResourceAsStream("/foo/bar.properties"); // works! MyClass.class.getClassLoader().getResourceAsStream("/foo/bar.properties"); // does NOT work! 

Извините, у меня нет абсолютно никакого объяснения, но я думаю, что tomcat делает грязные трюки и свою черную магию с загрузчиками classов и вызывают разницу. Я всегда использовал class.getResourceAsStream(String) в прошлом и не испытывал никаких проблем.

PS: Я также разместил это здесь

Class.getResources будет извлекать ресурс загрузчиком classов, который загружает объект. В то время как ClassLoader.getResource будет извлекать ресурс, используя указанный class загрузчика.

Я пробовал читать с input1.txt, который был внутри одного из моих пакетов вместе с classом, который пытался его прочитать.

Следующие работы:

 String fileName = FileTransferClient.class.getResource("input1.txt").getPath(); System.out.println(fileName); BufferedReader bufferedTextIn = new BufferedReader(new FileReader(fileName)); 

Наиболее важная часть заключалась в том, чтобы вызвать getPath() если вы хотите getPath() правильный путь в формате String. НЕ ИСПОЛЬЗУЙТЕ toString() потому что он добавит дополнительный текст форматирования, который будет ОБРАТИТЬСЯ к файловому имени (вы можете попробовать его и увидеть распечатку).

Отработано 2 часа отладки этого … 🙁

  • PLSQL JDBC: как получить идентификатор последней строки?
  • Как установить Datasource при создании Hibernate SessionFactory?
  • Почему у этого метода Java есть два типа возврата?
  • Закрытие управляемой JOptionPane
  • Какие методы компонента Swing являются streamобезопасными?
  • Что делает OSGi?
  • Java слишком много открытых файлов
  • java.lang.ClassNotFoundException, несмотря на использование переменной среды CLASSPATH
  • java swingworker thread для обновления основного Gui
  • Многослойное стекло GlassPane в корневом контейнере
  • Отменить заданное предложение в Java
  • Interesting Posts
    Давайте будем гением компьютера.