Что такое Java ClassLoader?

174

В нескольких простых предложениях, что такое Java ClassLoader, когда он используется и почему?

Хорошо, я прочитал статью в вики. ClassLoader загружает классы. ХОРОШО. Поэтому, если я включу jar-файлы и импортирую, ClassLoader сделает эту работу.

Почему я должен беспокоиться об этом ClassLoader? Я никогда не использовал это и не знал, что это существовало.

Вопрос в том, почему существует класс ClassLoader? А также, как вы используете это на практике? (Случаи существуют, я знаю.)

EugeneP
источник
Вы получите лучшие результаты, если сузите свой вопрос, например, указав конкретную часть, которую вы не понимаете, как она связана с другим языком, с которым вы знакомы, и т. Д.
JRL
75
Это вполне разумный вопрос, если рассматривать его с точки зрения того, что кто-то ищет несколько простых предложений для объяснения концепции
oxbow_lakes
Это видео может представлять интерес: действительно ли вы получаете загрузчики классов?
Asmaier

Ответы:

231

Взято из этого хорошего урока от Sun:

мотивация

Приложения, написанные на статически скомпилированных языках программирования, таких как C и C ++, компилируются в собственные, машинно-зависимые инструкции и сохраняются в виде исполняемого файла. Процесс объединения кода в исполняемый собственный код называется связыванием - объединением отдельно скомпилированного кода с кодом общей библиотеки для создания исполняемого приложения. Это отличается в динамически скомпилированных языках программирования, таких как Java. В Java файлы .class, сгенерированные компилятором Java, остаются как есть до тех пор, пока не будут загружены в виртуальную машину Java (JVM) - другими словами, процесс связывания выполняется JVM во время выполнения. Классы загружаются в JVM по мере необходимости. И когда загруженный класс зависит от другого класса, тогда этот класс также загружается.

Когда Java-приложение запускается, первый класс для запуска (или точка входа в приложение) - это класс с открытым статическим методом void, называемым main (). Этот класс обычно имеет ссылки на другие классы, и все попытки загрузить указанные классы выполняются загрузчиком классов.

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

public class HelloApp {
   public static void main(String argv[]) {
      System.out.println("Aloha! Hello and Bye");
   }
}

Если вы запустите этот класс, указав параметр -verbose: class для командной строки, чтобы он печатал, какие классы загружаются, вы получите вывод, который выглядит следующим образом. Обратите внимание, что это только частичный вывод, поскольку список слишком длинный для отображения здесь.

prmpt>java -verbose:class HelloApp



[Opened C:\Program Files\Java\jre1.5.0\lib\rt.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jsse.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jce.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\charsets.jar]
[Loaded java.lang.Object from shared objects file]
[Loaded java.io.Serializable from shared objects file]
[Loaded java.lang.Comparable from shared objects file]
[Loaded java.lang.CharSequence from shared objects file]
[Loaded java.lang.String from shared objects file]
[Loaded java.lang.reflect.GenericDeclaration from shared objects file]
[Loaded java.lang.reflect.Type from shared objects file]
[Loaded java.lang.reflect.AnnotatedElement from shared objects file]
[Loaded java.lang.Class from shared objects file]
[Loaded java.lang.Cloneable from shared objects file]
[Loaded java.lang.ClassLoader from shared objects file]
[Loaded java.lang.System from shared objects file]
[Loaded java.lang.Throwable from shared objects file]
.
.
.
[Loaded java.security.BasicPermissionCollection from shared objects file]
[Loaded java.security.Principal from shared objects file]
[Loaded java.security.cert.Certificate from shared objects file]
[Loaded HelloApp from file:/C:/classes/]
Aloha! Hello and Bye
[Loaded java.lang.Shutdown from shared objects file]
[Loaded java.lang.Shutdown$Lock from shared objects file]

Как видите, классы времени выполнения Java, требуемые классом приложения (HelloApp), загружаются первыми.

Загрузчики классов в платформе Java 2

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

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

Поскольку имеется более одного загрузчика классов, они представлены в дереве, корнем которого является загрузчик классов начальной загрузки. Каждый загрузчик классов имеет ссылку на свой родительский загрузчик классов. Когда загрузчику класса предлагается загрузить класс, он обращается к своему загрузчику родительского класса, прежде чем пытаться загрузить сам элемент. Родитель, в свою очередь, консультируется со своим родителем и так далее. Таким образом, только после того, как все загрузчики класса-предка не могут найти класс, текущий загрузчик класса подключается. Другими словами, используется модель делегирования.

Класс java.lang.ClassLoader

Это java.lang.ClassLoaderабстрактный класс, который может быть разделен на подклассы приложениями, которым необходимо расширить способ динамической загрузки классов JVM. Конструкторы в java.lang.ClassLoader(и его подклассах) позволяют вам указывать родителя, когда вы создаете новый загрузчик классов. Если вы не укажете явно родительский объект, загрузчик системного класса виртуальной машины будет назначен родительским по умолчанию. Другими словами, класс ClassLoader использует модель делегирования для поиска классов и ресурсов. Таким образом, каждый экземпляр ClassLoader имеет связанный родительский загрузчик классов, поэтому при запросе на поиск класса или ресурсов задача делегируется его родительскому загрузчику классов перед попыткой найти сам класс или ресурс. loadClass()Метод ClassLoader выполняет следующие задачи, для того, когда вызывается для загрузки класса:

Если класс уже загружен, он возвращает его. В противном случае он делегирует поиск нового класса загрузчику родительского класса. Если загрузчик родительского класса не находит класс, loadClass()вызывает метод findClass()для поиска и загрузки класса. В finalClass()поисках метода для класса в текущем загрузчике класса , если класс не был найдены родительским загрузчиком классов.


В исходной статье есть еще кое-что, в котором также показано, как реализовать собственные загрузчики сетевых классов, и ответ на ваш вопрос, почему (и как). Смотрите также документы API .

JRL
источник
47

Большинству разработчиков Java никогда не потребуется явно использовать загрузчики классов (кроме как для загрузки ресурсов, чтобы они все еще работали, когда они объединены в JAR), не говоря уже о написании своих собственных.

ClassLoaders используются в больших системах и серверных приложениях для таких вещей, как:

  • Модульная система и загрузка, выгрузка и обновление модулей во время выполнения
  • Используйте разные версии библиотеки API (например, анализатор XML) параллельно
  • Изолировать разные приложения, работающие в одной JVM (убедитесь, что они не мешают друг другу, например, через статические переменные)
Майкл Боргвардт
источник
29

Вопрос заключается в том, «зачем беспокоиться о существовании этого класса ClassLoader»?

Ну, в основном, чтобы вы могли что-то исправить, если они пошли не так :-).

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

Тем не менее, полезно немного узнать о загрузчиках классов и загрузке классов, чтобы лучше понять, что происходит за кулисами. Например, «статические инициализаторы» будут запускаться при загрузке класса, поэтому, чтобы понять, когда они будут работать, вам нужно знать, как загрузчик классов решает, когда их загружать.

также .. как вы используете это на практике?

Для простых случаев они вам не нужны. Однако, если вам нужно динамически загружать код во время выполнения с явным контролем, откуда он поступает (например, загрузка по сети, загрузка плагинов, недоступных во время компиляции и т. Д.), Вам может потребоваться сделать больше. Тогда вы можете, например, написать свой собственный загрузчик классов. Смотрите другие ответы для ссылок.

sleske
источник
14

ClassLoaderв Java это класс, который используется для загрузки файлов классов в Java. Код Java компилируется в файл класса javacкомпилятором, а JVM выполняет программу Java, выполняя байтовые коды, записанные в файле класса.

ClassLoader отвечает за загрузку файлов классов из файловой системы, сети или любого другого источника. Существует три загрузчика классов по умолчанию, используемых в загрузчике классов Java, Bootstrap , Extension и System или Application .

ClassLoader


Как работает ClassLoader

## взаимодействие ClassLoader с JVM введите описание изображения здесь

Больше @: how-classloader-works-in-java.html

roottraveller
источник
6

Загрузчики классов являются функциональным компонентом JVM, который загружает данные классов из файла .class или по сети в область метода в куче.

Выглядит как неотъемлемая часть JVM, но как конечный пользователь Java, почему я должен быть обеспокоен? Вот почему:

Каждый загрузчик классов имеет свое собственное пространство имен, и классы, вызываемые определенным загрузчиком классов, попадают в его пространство имен.

Классы, вызываемые двумя различными загрузчиками классов, не будут иметь видимости друг над другом, что приведет к повышению безопасности.

Механизм родительского дочернего делегирования загрузчика классов гарантирует, что классы Java-API никогда не будут взломаны неавторизованным кодом.

Подробности смотрите здесь

Bitan
источник
1

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

Как загружается самый первый класс?
Самый первый класс загружается с помощью static main()метода, объявленного в вашем классе. Все впоследствии загруженные классы загружаются классами, которые уже загружены и работают.

Загрузчик классов создает пространство имен. Все JVM включают в себя как минимум один загрузчик классов, который встроен в JVM и называется загрузчиком классов первичного (или начального) класса. Это одна вещь, и мы рассмотрим неисключительные загрузчики классов. В JVM есть зацепки, позволяющие использовать загрузчики классов, определенные пользователем, вместо изначального загрузчика классов. Вот загрузчики классов, созданные JVM.

Bootstrap (изначальный) Этот загрузчик классов не загружается повторно. Загружает внутренние классы JDK, пакеты java. * (Обычно загружает rt.jar и i18n.jar). Расширения Этот загрузчик классов не загружается повторно. Загружает файлы JAR из каталога расширений JDK (обычно это lib / ext из JRE). Система Этот загрузчик классов не может быть загружен повторно. Загружает классы из системного пути к классам.

http://www.sbalasani.com/2015/01/java-class-loaders.html

Сринивас Баласани
источник
1

Когда вы спрашиваете, почему существует класс ClassLoader, причина довольно проста - это класс, отвечающий за поиск и загрузку файлов классов во время выполнения .

Давайте уточним это.

В JVM каждый класс загружается некоторым экземпляром java.lang.ClassLoader. Всякий раз, когда вы запускаете новую JVM вашей обычной java <classname>командой запуска Java-программы , первым шагом является загрузка всех ключевых классов в память, необходимую для правильной работы, как java.lang.Objectи другие классы времени выполнения ( rt.jar).

Теперь в ClassLoader есть 3 части:

  • BootstrapClassLoaderНесет ответственность за эти классы доступны есть загрузка этих классов в памяти.

  • Следующая задача - загрузить любые внешние библиотеки / JAR-файлы в память для правильной работы приложения. ExtClassLoaderОтвечает за эту задачу. Этот загрузчик классов отвечает за загрузку всех файлов .jar, указанных в пути java.ext.dirs.

  • Третий и самый важный загрузчик классов - это AppClassLoader . Загрузчик классов приложения отвечает за загрузку файлов классов, указанных в системном свойстве java.class.path.

Также важно отметить, что стандартные реализации ClassLoader могут быть переопределены, что позволит вам настраивать JVM полезными и интересными способами, позволяя вам полностью переопределить, как файлы классов вводятся в систему.

введите описание изображения здесь

Проверьте это, чтобы узнать больше о Java Class Loader .

Джонни
источник