Модель делегации ClassLoder Java?

При вызове loadClass() на a ClassLoader, делает ClassLoader сначала проверьте, был ли класс загружен или делает это, сразу делегируют эту проверку к ее родителю ClassLoader?

Java API говорит:

При необходимости для нахождения класса или ресурса экземпляр ClassLoder делегирует поиск класса или ресурса к его загрузчику родительского класса прежде, чем попытаться найти класс или сам ресурс.

Но существует определенная глава о загрузчике класса в книжном Отражении Java в Действии, которое говорит:

Загрузчик класса называет findLoadedClass, чтобы проверить, был ли класс уже загружен. Если загрузчик класса не находит загруженный класс, loadClass вызовов на загрузчике родительского класса.

Который корректен?

12
задан Hearen 19 March 2019 в 11:07
поделиться

6 ответов

Правильная реализация загрузчика классов:

  1. Проверяет, был ли уже загружен класс.
  2. Обычно просят загрузчик родительского класса загрузить класс
  3. Попытка найти класс в его собственном пути к классам.

Реализация ClassLoader.loadClass по умолчанию выглядит примерно так:

protected synchronized Class<?> loadClass(String name, boolean resolve) {
  // First, check if this class loader has directly defined the class or if the
  // JVM has initiated the class load with this class loader.
  Class<?> result = findLoadedClass(name);
  if (result == null) {
    try {
      // Next, delegate to the parent.
      result = getParent().loadClass(name);
    } catch (ClassNotFoundException ex) {
      // Finally, search locally if the parent could not find the class.
      result = findClass(ex);
    }
  }
  // As a remnant of J2SE 1.0.2, link the class if a subclass of the class
  // loader class requested it (the JVM never calls the method,
  // loadClass(String) passes false, and the protected access modifier prevents
  // callers from passing true).
  if (resolve) {
    resolveClass(result);
  }
  return result;
}

Некоторые реализации загрузчика классов будут делегировать другим загрузчикам классов, не являющимся родительскими (OSGi, например, делегирует графу загрузчиков классов в зависимости от пакета), и некоторые реализации загрузчика классов будут искать классы в локальном пути к классам перед делегированием.

17
ответ дан 2 December 2019 в 07:02
поделиться

В основном это работает. Вы набираете

Foo f = new Foo();

. На этом этапе загрузчик классов определит, загружен ли Foo () , а именно его биты в памяти / perm gen. Если он был загружен, используйте его. В противном случае делегируйте его загрузчику родительского класса, чтобы попытаться разрешить класс. Биты этого класса считываются с диска, а затем загружаются в память. При следующем new Foo () класс теперь будет найден в памяти / загружен.

1
ответ дан 2 December 2019 в 07:02
поделиться

Чтобы согласиться с ответом Шри, он всегда будет делегироваться родителю, а api верен. Если вы играете с загрузкой классов, это может немного усложнить задачу или добиться желаемых эффектов. Я бы посоветовал запустить jvm с минимальным путем к классам, а затем загрузить все классы с помощью пользовательского загрузчика классов. Самый простой способ сделать это - использовать URLClassloader или составной объект, обертывающий URLClassloader, чтобы вы могли отслеживать, какие классы загружаются и когда.

Также стоит иметь в виду, что класс A, загруженный загрузчиком классов C! = Класс A, загруженный загрузчиком классов C, если C и D не являются частью одной и той же иерархии загрузчик классов-родитель-потомок.

0
ответ дан 2 December 2019 в 07:02
поделиться

API Java верен.

При запросе на поиск класса или ресурса экземпляр ClassLoader делегирует поиск класса или ресурса своему родительскому загрузчику классов перед попытка найти сам класс или ресурс.

Из Механизма загрузки классов Java -

При загрузке класса загрузчик класса сначала «делегирует» поиск класса своему загрузчику родительского класса, прежде чем пытаться найти сам класс.

2
ответ дан 2 December 2019 в 07:02
поделиться

Эти два оператора не являются взаимоисключающими. Класс будет существовать только в текущем наборе загруженных классов ClassLoader, если родительский ClassLoader ранее не смог найти класс. Итак,

При запросе на поиск (внешних данных, описывающих) класс или ресурс, экземпляр ClassLoader делегирует поиск (внешние данные, которые описывают) класс или { {1}} в загрузчик родительского класса перед попыткой найти (описывающие внешние данные) сам класс или ресурс.

Что не предотвращает его короткое замыкание, если он знает, что его родительский элемент не может найти класс, но он может (как показано ранее загрузкой класса)

2
ответ дан 2 December 2019 в 07:02
поделиться

В этом контексте следует отметить еще одну проблему. В документе API говорится:

Методы и конструкторы объекты, созданные загрузчиком классов, могут ссылаться на другие классы. Чтобы определить упомянутые классы, Java виртуальная машина вызывает loadClass метод загрузчика классов, который изначально создал класс.

Это означает, что сети ссылающихся классов загружаются одним и тем же загрузчиком классов.

0
ответ дан 2 December 2019 в 07:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: