В чем разница между getResourceAsStream с и без getClassLoader?

Я хотел бы узнать разницу между следующими двумя:

MyClass.class.getClassLoader().getResourceAsStream("path/to/my/properties");

и

MyClass.class.getResourceAsStream("path/to/my/properties");

Спасибо.

Ответ 1

Из Javadoc для Class.getResourceAsStream():

Этот метод делегирует этот загрузчик класса объекта. Перед делегированием из данного имени ресурса создается имя абсолютного ресурса с использованием этого алгоритма:

  • Если name начинается с '/' ('\ u002f'), то абсолютное имя ресурса является частью имени, следующего за '/'.
  • В противном случае абсолютное имя имеет следующий вид: modified_package_name/name
    Где modified_package_name - это имя пакета этого объекта с заменой '/' на '.' ( '\ U002e').

Другими словами, они делают то же самое, если "путь" начинается с "/", но если нет, то в последнем случае путь будет относиться к пакету класса, тогда как загрузчик классов будет абсолют.

Короче говоря, первые выборки path/to/my/properties и второй выборки package/of/myclass/path/to/my/properties.

Ответ 2

Из Class.getClassLoader() документация:

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

So getClassLoader() может возвращать null, если класс загружен загрузчиком класса загрузки, поэтому нулевая проверка в Class.getResourceAsStream реализация:

public InputStream getResourceAsStream(String name) {
    name = resolveName(name);
    ClassLoader cl = getClassLoader0();
    if (cl==null) {
        // A system class.
        return ClassLoader.getSystemResourceAsStream(name);
    }
    return cl.getResourceAsStream(name);
}

Вы также обратите внимание на выражение name = resolveName(name);, которое Марк Петерс объяснил в своем ответе.

Ответ 3

Основное практическое отличие состоит в том, что вы можете использовать относительные пути при прохождении класса. Поэтому, если ваши свойства находятся в том же пакете, что и MyClass, вы можете сделать

MyClass.class.getResourceAsStream("properties");