Что такое Java ClassLoader?
В нескольких простых предложениях, что такое Java ClassLoader, когда он используется и почему?
Хорошо, я прочитал статью в вики. ClassLoader загружает классы. ХОРОШО. Поэтому, если я включу jar-файлы и импортирую, ClassLoader сделает эту работу.
Почему я должен беспокоиться об этом ClassLoader? Я никогда не использовал это и не знал, что это существовало.
Вопрос в том, почему существует класс ClassLoader? А также, как вы используете это на практике? (Случаи существуют, я знаю.)
8 ответов
Взято из этого хорошего урока от 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.Class Loader
java.lang.ClassLoader
абстрактный класс, который может быть разделен на подклассы приложениями, которым необходимо расширить способ динамической загрузки классов JVM. Конструкторы в java.lang.ClassLoader
(и его подклассы) позволяют указать родителя при создании нового загрузчика классов. Если вы не укажете явно родительский объект, загрузчик системного класса виртуальной машины будет назначен родительским по умолчанию. Другими словами, класс Class Loader использует модель делегирования для поиска классов и ресурсов. Поэтому с каждым экземпляром Class Loader связан родительский загрузчик классов, поэтому при запросе на поиск класса или ресурсов задача делегируется его родительскому загрузчику класса перед попыткой найти сам класс или ресурс. loadClass()
Метод Class Loader выполняет следующие задачи по порядку при вызове для загрузки класса:
Если класс уже загружен, он возвращает его. В противном случае он делегирует поиск нового класса загрузчику родительского класса. Если родительский загрузчик класса не находит класс, loadClass()
вызывает метод findClass()
найти и загрузить класс. finalClass()
Метод ищет класс в текущем загрузчике классов, если класс не был найден загрузчиком родительского класса.
В исходной статье есть еще кое-что, в котором также показано, как реализовать собственные загрузчики сетевых классов, и ответ на ваш вопрос, почему (и как). Смотрите также API документы.
Большинству разработчиков Java никогда не понадобится явно использовать загрузчики классов (кроме как для загрузки ресурсов, чтобы они все еще работали, когда они объединены в JAR), не говоря уже о том, чтобы писать свои собственные.
ClassLoaders используются в больших системах и серверных приложениях для таких вещей, как:
- Модульная система и загрузка, выгрузка и обновление модулей во время выполнения
- Используйте разные версии библиотеки API (например, анализатор XML) параллельно
- Выделите разные приложения, работающие в одной и той же JVM (убедитесь, что они не мешают друг другу, например, через статические переменные)
Вопрос в том, "Зачем беспокоиться о существовании этого класса ClassLoader"?
Ну, в основном, так что вы можете исправить вещи, если они пойдут не так:-).
Это правда, если вы просто напишите приложение, скомпилируете его в JAR и, возможно, включите несколько дополнительных библиотечных JAR, вам не нужно знать о загрузчиках классов, это будет просто работать.
Тем не менее, полезно немного узнать о загрузчиках классов и загрузке классов, чтобы лучше понять, что происходит за кулисами. Например, "статические инициализаторы" будут запускаться при загрузке класса, поэтому, чтобы понять, когда они будут работать, вам нужно знать, как загрузчик классов решает, когда их загружать.
также.. как вы используете это на практике?
Для простых случаев они вам не нужны. Однако, если вам нужно динамически загружать код во время выполнения с явным контролем, откуда он поступает (например, загрузка по сети, загрузка плагинов, недоступных во время компиляции и т. Д.), Вам может потребоваться сделать больше. Тогда вы можете, например, написать свой собственный загрузчик классов. Смотрите другие ответы для ссылок.
ClassLoader
в Java это класс, который используется для загрузки файлов классов в Java. Java-код компилируется в файл класса javac
Компилятор и JVM выполняют программу Java, выполняя байтовые коды, записанные в файле класса.
ClassLoader отвечает за загрузку файлов классов из файловой системы, сети или любого другого источника. Существует три загрузчика классов по умолчанию, используемых в загрузчике классов Java, Bootstrap, Extension и System или Application.
## Взаимодействие ClassLoader с JVM
Больше @: http://javarevisited.blogspot.in/2012/12/how-classloader-works-in-java.html
Загрузчики классов являются функциональным компонентом JVM, который загружает данные классов из файла.class или по сети в область метода в куче.
Выглядит как неотъемлемая часть JVM, но как конечный пользователь Java, почему я должен быть обеспокоен? Вот почему:
Каждый загрузчик классов имеет свое собственное пространство имен, и классы, вызываемые определенным загрузчиком классов, попадают в его пространство имен.
Классы, вызываемые двумя различными загрузчиками классов, не будут иметь видимости друг над другом, что приведет к повышению безопасности.
Механизм родительского дочернего делегирования загрузчика классов гарантирует, что классы Java-API никогда не будут взломаны неавторизованным кодом.
Подробности смотрите здесь
Когда вы спрашиваете, почему существует класс ClassLoader, причина довольно проста - это класс, отвечающий за поиск и загрузку файлов классов во время выполнения.
Давайте уточним это.
В JVM каждый класс загружается некоторым экземпляром java.lang.ClassLoader
. Всякий раз, когда новая JVM запускается, вы запускаете обычную программу Javajava <classname>
команда, первый шаг - загрузить в память все ключевые классы, необходимые для правильной работы, например java.lang.Object
и другие классы времени выполнения (rt.jar
).
На самом деле ClassLoader состоит из трех частей:
В
BootstrapClassLoader
отвечает за предоставление доступа к этим классам, то есть за загрузку этих классов в память.Следующая задача - загрузить в память любые внешние библиотеки / JAR-файлы для правильной работы приложения. В
ExtClassLoader
отвечает за эту задачу. Этот загрузчик классов отвечает за загрузку всех файлов.jar, указанных в пути java.ext.dirs.Третий и главный загрузчик классов - это
AppClassLoader
. Загрузчик классов приложения отвечает за загрузку файлов классов, указанных в системном свойстве java.class.path.
Также важно отметить, что реализации ClassLoader по умолчанию могут быть переопределены, что позволит вам настроить JVM полезными и интересными способами, что позволит вам полностью переопределить способ передачи файлов классов в систему.
Ознакомьтесь с ним, чтобы узнать больше о загрузчике классов Java.
Загрузчики классов являются иерархическими. Классы вводятся в JVM, так как на них ссылаются по имени в классе, который уже запущен в JVM.
Как загружается самый первый класс?
Самый первый класс загружается с помощью static main()
метод объявлен в вашем классе. Все впоследствии загруженные классы загружаются классами, которые уже загружены и работают.
Загрузчик классов создает пространство имен. Все JVM включают в себя как минимум один загрузчик классов, который встроен в JVM и называется загрузчиком классов первичного (или начального) класса. Это одна вещь, и мы рассмотрим неисключительные загрузчики классов. В JVM есть зацепки, позволяющие использовать загрузчики классов, определенные пользователем, вместо первоначального загрузчика классов. Вот загрузчики классов, созданные JVM.
Bootstrap (изначальный) Этот загрузчик классов не загружается повторно. Загружает внутренние классы JDK, пакеты java.* (Обычно загружает rt.jar и i18n.jar). Расширения Этот загрузчик классов не загружается повторно. Загружает файлы JAR из каталога расширений JDK (обычно это lib/ext из JRE). Система Этот загрузчик классов не загружается повторно. Загружает классы из системного пути к классам.
ClassLoader
ClassLoader
является частью JRE(Java Runtime Environment), которая динамически загружает классы (объекты envirompment -
java.lang.Class
и файлы
.class
) в JVM (виртуальную машину Java). JRE использует отложенную загрузку классов (по запросу), это может уменьшить объем памяти. Когда приложению требуется какой-то класс, JRE просит ClassLoader загрузить этот класс
Есть иерархия класса ClassLoader
- BootStrap или Primodial - корневой и встроенный (возвращает null, когда getClassLoader()) классы JDK. Загружает классы из rt.jar
- Расширение (платформа Java v9) - базовые классы Java. Загружает классы из каталога jre / lib / ext или указывает системное свойство java.ext.dirs
- Система / Приложение - классы приложений из
classpath
<sup>[О программе]</sup> или параметр командной строки (-cp, -classpath)
Также вы можете создать свой собственный класс ClassLoader для вашего конкретного случая. Например загрузка класса из некоторого репозитория, работа с версией, выгрузкой, безопасностью
Чтобы проверить, кто именно загружает ваш класс, используйте
getClassLoader()
SomeClass.class.getClassLoader()
Поиск потока классов (модель делегирования)
child classloader find in cache
if not
parent classloader find in cache
if not
parent classloader try to load
if not
child classloader try to load
[ClassNotFoundException vs NoClassDefFoundError и неявная vs явная загрузка класса]