Что такое classloader java
Внутренности JVM, Часть 1 — Загрузчик классов
Перевод статьи подготовлен специально для студентов курса «Разработчик Java».
В этой серии статей я расскажу о том, как работает Java Virtual Machine. Сегодня мы рассмотрим механизм загрузки классов в JVM.
Виртуальная машина Java — это сердце экосистемы Java-технологий. Она делает для Java-программ возможность реализации принципа «написано один раз, работает везде» (write once run everywhere). Как и другие виртуальные машины, JVM представляет собой абстрактный компьютер. Основная задача JVM — загружать class-файлы и выполнять содержащийся в них байт-код.
В состав JVM входят различные компоненты, такие как загрузчик классов (Classloader), сборщик мусора (Garbage Collector) (автоматическое управление памятью), интерпретатор, JIT-компилятор, компоненты управления потоками. В этой статье рассмотрим загрузчик классов (Class loader).
Загрузчик классов загружает class-файлы как для вашего приложения, так и для Java API. В виртуальную машину загружаются только те class-файлы Java API, которые действительно требуются при выполнении программы.
Байт-код выполняется подсистемой исполнения (execution engine).
Что такое загрузка классов?
Загрузка классов — это поиск и загрузка типов (классов и интерфейсов) динамически во время выполнения программы. Данные о типах находятся в бинарных class-файлах.
Этапы загрузки классов
Подсистема загрузчика классов отвечает не только за поиск и импорт бинарных данных класса. Она также выполняет проверку правильности импортируемых классов, выделяет и инициализирует память для переменных класса, помогает в разрешении символьных ссылок. Эти действия выполняются в следующем порядке:
Примечание — загрузчик классов, помимо загрузки классов, также отвечает за поиск ресурсов. Ресурс — это некоторые данные (например, “.class” файл, данные конфигурации, изображения), которые идентифицируются с помощью абстрактного пути, разделенного символом «/». Ресурсы обычно упаковываются вместе с приложением или библиотекой для того, чтобы их можно было использовать в коде приложения или библиотеки.
Механизм загрузки классов в Java
Platform class loader — загружает выбранные (на основе безопасности / разрешений) модули Java SE и JDK. Например, java.sql.
Bootstrap class loader — загружает основные модули Java SE и JDK.
Эти три встроенных загрузчика классов работают вместе следующим образом:
Запустив этот код на установленном у меня Amazon Corretto 11.0.3, получим следующий результат:
Подробнее изучить ClassLoader API вы можете здесь (JDK 11).
Как происходит загрузка классов в JVM
Загрузчик классов
загрузка байт-кода из ресурсов и создание экземпляра класса Class
сюда входит поиск запрошенного класса среди загруженных ранее, получение байт-кода для загрузки и проверка его корректности, создание экземпляра класса Class (для работы с ним в runtime), загрузка родительских классов. Если родительские классы и интерфейсы не были загружены, то и рассматриваемый класс считается не загруженным.
связывание (или линковка)
по спецификации этот этап разбивается еще на три стадии:
инициализация полученного объекта
здесь, в отличие от предыдущих пунктов, вроде бы все понятно, что должно происходить. Было бы, конечно, интересно разобраться как именно это происходит.
Типы загрузчиков Java
Bootstrap – базовый загрузчик, также называется Primordial ClassLoader.
загружает стандартные классы JDK из архива rt.jar
Extension ClassLoader – загрузчик расширений.
загружает классы расширений, которые по умолчанию находятся в каталоге jre/lib/ext, но могут быть заданы системным свойством java.ext.dirs
System ClassLoader – системный загрузчик.
загружает классы приложения, определенные в переменной среды окружения CLASSPATH
В Java используется иерархия загрузчиков классов, где корневым, разумеется, является базовый. Далее следует загрузчик расширений, а за ним уже системный. Естественно, каждый загрузчик хранит указатель на родительский для того, чтобы смочь делегировать ему загрузку в том случае, если сам будет не в состоянии этого сделать.
Абстрактный класс ClassLoader
Три принципа загрузки классов
Делегирование
Запрос на загрузку класса передается родительскому загрузчику, и попытка загрузить класс самостоятельно выполняется, только если родительский загрузчик не смог найти и загрузить класс. Такой подход позволяет загружать классы тем загрузчиком, который максимально близко находится к базовому. Так достигается максимальная область видимости классов. Каждый загрузчик ведет учет классов, которые были загружены именно им, помещая их в свой кэш. Множество этих классов и называется областью видимости.
Видимость
Загрузчик видит только «свои» классы и классы «родителя» и понятия не имеет о классах, которые были загружены его «потомком».
Уникальность
Класс может быть загружен только однажды. Механизм делегирования позволяет убедиться, что загрузчик, инициирующий загрузку класса, не перегрузит загруженный ранее в JVM класс.
Таким образом, при написании своего загрузчика разработчик должен руководствоваться этими тремя принципами.
ClassLoader в Java
ClassLoader в Java вызывается средой выполнения для динамической загрузки классов, когда это требуется приложением на виртуальной машине. Поскольку загрузчики классов являются частью среды выполнения, виртуальная машина не будет иметь никакого представления о базовых файлах и файловых системах.
Расширение
Загружает расширения основных классов Java из библиотеки расширений JDK. Он является дочерним элементом Bootstrap и загружает расширения из каталога JRE / lib / text или любого другого каталога, указанного в системном свойстве java.ext.dirs.
Приложение или Система
Загрузчик
Как все мы знаем, что Java-классы загружаются экземпляром java.lang.ClassLoade. Но поскольку ClassLoaders являются классами, Bootstrap отвечает за загрузку внутренних классов JDK. Представляет собой машинный код, который запускает операцию, когда JVM вызывает ее и загружает классы из rt.jar. Таким образом, вы можете понять, что служба Bootstrap не имеет родительского ClassLoader и, таким образом, называется Primordial ClassLoader.
Примечание. Приоритет Bootstrap выше, чем Extension, а приоритет, присвоенный Extension ClassLoader, выше, чем Application ClassLoader. Обратитесь к изображению ниже:
Принципы
Набор правил, на основе которых работает Java ClassLoader, состоит из следующих трех принципов:
Свойство уникальности
Это свойство гарантирует, что нет повторения классов, и все классы являются уникальными. Свойство уникальности также гарантирует, что классы, загружаемые родительским ClassLoader, не загружаются дочерним. В сценарии, где родительский ClassLoader не может найти класс, текущий экземпляр попытается сделать это самостоятельно.
Модель делегирования
ClassLoader работает на основе набора операций, заданных моделью делегирования. Таким образом, всякий раз, когда генерируется запрос на поиск класса или ресурса, экземпляр ClassLoader делегирует поиск класса или ресурса родительскому ClassLoader.
Набор операций, на основе которых работает ClassLoader:
Обратитесь к изображению ниже.
Принцип видимости
Согласно этому принципу, дочерние классы видны для классов, загруженных их родительскими ClassLoaders, но наоборот не соответствует действительности. Таким образом, классы, загруженные приложением ClassLoader, имеют видимость классов, загруженных расширением и загрузчиком ClassLoader.
Например, если у нас есть два класса: AB, предположим, что класс A загружается приложением ClassLoader, а класс B загружается расширением ClassLoader. Здесь классы A и B видны всем тем классам, которые загружены приложением ClassLoader, но класс B виден только тем классам, которые загружены расширением ClassLoader.
Кроме того, если вы попытаетесь загрузить эти классы с помощью загрузчика ClassLoader, вы увидите. исключение.
Методы
Вот несколько основных методов ClassLoader:
loadClass (имя строки, логическое разрешение)
Этот метод является точкой входа ClassLoader и используется для загрузки класса, на который ссылается JVM. Он принимает имя класса в качестве параметра. JVM вызывает метод loadClass() для разрешения ссылок на класс, устанавливая логическое значение true. Только если нам нужно определить, существует ли класс или нет, логический параметр имеет значение false.
defineClass()
Последний метод, используемый для определения массива байтов как экземпляра класса. В случае, если класс недопустим, он выдает ClassFormatError.
findClass (Строковое имя)
Используется для поиска указанного класса. Таким образом, он просто находит класс с полностью определенным именем в качестве параметра, но не загружает класс. Метод loadClass() вызывает этот метод, если родительский ClassLoader не может найти запрошенный класс. Кроме того, если ни один из родителей ClassLoader не находит класс, реализация по умолчанию генерирует исключение ClassNotFoundException.
Class.forName (имя строки, логическая инициализация, загрузчик ClassLoader)
Этот метод используется для загрузки и инициализации класса. Это дает возможность выбрать любой из ClassLoaders и в случае, если параметр ClassLoader равен NULL, тогда автоматически используется Bootstrap ClassLoader.
GetParent()
Используется для возврата родительского ClassLoader для делегирования.
getResource()
Пытается найти ресурс с заданным именем. Первоначально он делегирует запрос родительскому ClassLoader для ресурса. Если родительский объект имеет значение null, то ищется путь к ClassLoader, встроенному в JVM. Теперь, если это не удается, тогда метод вызовет findResource(String), чтобы найти ресурс, где имя ресурса указывается в качестве входных данных, которые могут быть как абсолютным, так и относительным путем к классу. Затем он возвращает объект URL для чтения ресурса или возвращает нулевое значение, если у ресурса нет достаточных прав для возврата ресурса или он не найден.
Пользовательский
Встроенные ClassLoaders позаботятся о большинстве случаев, когда файлы уже находятся в файловой системе, но если вы хотите загрузить классы с локального жесткого диска, вам нужно использовать пользовательские ClassLoaders.
Чтобы создать собственный ClassLoader, вам нужно расширить класс ClassLoader и переопределить метод findClass():
Средняя оценка / 5. Количество голосов:
Или поделись статьей
Видим, что вы не нашли ответ на свой вопрос.
Что такое classloader java
Class objects for array classes are not created by class loaders, but are created automatically as required by the Java runtime. The class loader for an array class, as returned by Class.getClassLoader() is the same as the class loader for its element type; if the element type is a primitive type, then the array class has no class loader.
Applications implement subclasses of ClassLoader in order to extend the manner in which the Java virtual machine dynamically loads classes.
Class loaders may typically be used by security managers to indicate security domains.
The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader. When requested to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself. The virtual machine’s built-in class loader, called the «bootstrap class loader», does not itself have a parent but may serve as the parent of a ClassLoader instance.
Normally, the Java virtual machine loads classes from the local file system in a platform-dependent manner. For example, on UNIX systems, the virtual machine loads classes from the directory defined by the CLASSPATH environment variable.
For example, an application could create a network class loader to download class files from a server. Sample code might look like:
Binary names
Examples of valid class names include:
Constructor Summary
Method Summary
Methods inherited from class java.lang.Object
Constructor Detail
ClassLoader
ClassLoader
Method Detail
loadClass
loadClass
Invoke findLoadedClass(String) to check if the class has already been loaded.
Invoke the findClass(String) method to find the class.
If the class was found using the above steps, and the resolve flag is true, this method will then invoke the resolveClass(Class) method on the resulting Class object.
getClassLoadingLock
findClass
defineClass
defineClass
defineClass
defineClass
An invocation of this method of the form cl.defineClass(name, bBuffer, pd) yields exactly the same result as the statements
.
byte[] temp = new byte[bBuffer. remaining ()];
bBuffer. get (temp);
return cl.defineClass (name, temp, 0, temp.length, pd);
resolveClass
findSystemClass
findLoadedClass
setSigners
getResource
The name of a resource is a ‘/‘-separated path name that identifies the resource.
This method will first search the parent class loader for the resource; if the parent is null the path of the class loader built-in to the virtual machine is searched. That failing, this method will invoke findResource(String) to find the resource.
getResources
The name of a resource is a /-separated path name that identifies the resource.
findResource
findResources
registerAsParallelCapable
Note that once a class loader is registered as parallel capable, there is no way to change it back.
getSystemResource
getSystemResources
getResourceAsStream
getSystemResourceAsStream
getParent
getSystemClassLoader
This method is first invoked early in the runtime’s startup sequence, at which point it creates the system class loader and sets it as the context class loader of the invoking Thread.
The default system class loader is an implementation-dependent instance of this class.
If the system property «java.system.class.loader» is defined when this method is first invoked then the value of that property is taken to be the name of a class that will be returned as the system class loader. The class is loaded using the default system class loader and must define a public constructor that takes a single parameter of type ClassLoader which is used as the delegation parent. An instance is then created using this constructor with the default system class loader as the parameter. The resulting class loader is defined to be the system class loader.
definePackage
getPackage
getPackages
findLibrary
setDefaultAssertionStatus
setPackageAssertionStatus
A subpackage of a package named p is any package whose name begins with «p.«. For example, javax.swing.text is a subpackage of javax.swing, and both java.util and java.lang.reflect are subpackages of java.
In the event that multiple package defaults apply to a given class, the package default pertaining to the most specific package takes precedence over the others. For example, if javax.lang and javax.lang.reflect both have package defaults associated with them, the latter package default applies to classes in javax.lang.reflect.
setClassAssertionStatus
If the named class is not a top-level class, this invocation will have no effect on the actual assertion status of any class.
Что такое classloader java
Class objects for array classes are not created by class loaders, but are created automatically as required by the Java runtime. The class loader for an array class, as returned by Class.getClassLoader() is the same as the class loader for its element type; if the element type is a primitive type, then the array class has no class loader.
Applications implement subclasses of ClassLoader in order to extend the manner in which the Java virtual machine dynamically loads classes.
Class loaders may typically be used by security managers to indicate security domains.
The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader. When requested to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself. The virtual machine’s built-in class loader, called the «bootstrap class loader», does not itself have a parent but may serve as the parent of a ClassLoader instance.
Normally, the Java virtual machine loads classes from the local file system in a platform-dependent manner. For example, on UNIX systems, the virtual machine loads classes from the directory defined by the CLASSPATH environment variable.
For example, an application could create a network class loader to download class files from a server. Sample code might look like:
Binary names
Examples of valid class names include:
Constructor Summary
Modifier | Constructor and Description |
---|---|
protected | ClassLoader() |
Method Summary
Modifier and Type | Method and Description |
---|---|
void | clearAssertionStatus() |
Methods inherited from class java.lang.Object
Constructor Detail
ClassLoader
ClassLoader
Method Detail
loadClass
loadClass
Invoke findLoadedClass(String) to check if the class has already been loaded.
Invoke the findClass(String) method to find the class.
If the class was found using the above steps, and the resolve flag is true, this method will then invoke the resolveClass(Class) method on the resulting Class object.
getClassLoadingLock
findClass
defineClass
defineClass
defineClass
The specified name cannot begin with «java.«, since all classes in the «java.* packages can only be defined by the bootstrap class loader. If name is not null, it must be equal to the binary name of the class specified by the byte array «b«, otherwise a NoClassDefFoundError will be thrown.
defineClass
An invocation of this method of the form cl.defineClass(name, bBuffer, pd) yields exactly the same result as the statements
resolveClass
findSystemClass
findLoadedClass
setSigners
getResource
The name of a resource is a ‘/‘-separated path name that identifies the resource.
This method will first search the parent class loader for the resource; if the parent is null the path of the class loader built-in to the virtual machine is searched. That failing, this method will invoke findResource(String) to find the resource.
getResources
The name of a resource is a /-separated path name that identifies the resource.
findResource
findResources
registerAsParallelCapable
The registration succeeds if and only if all of the following conditions are met:
1. no instance of the caller has been created
2. all of the super classes (except class Object) of the caller are registered as parallel capable
Note that once a class loader is registered as parallel capable, there is no way to change it back.
getSystemResource
getSystemResources
getResourceAsStream
getSystemResourceAsStream
getParent
getSystemClassLoader
This method is first invoked early in the runtime’s startup sequence, at which point it creates the system class loader and sets it as the context class loader of the invoking Thread.
The default system class loader is an implementation-dependent instance of this class.
If the system property «java.system.class.loader» is defined when this method is first invoked then the value of that property is taken to be the name of a class that will be returned as the system class loader. The class is loaded using the default system class loader and must define a public constructor that takes a single parameter of type ClassLoader which is used as the delegation parent. An instance is then created using this constructor with the default system class loader as the parameter. The resulting class loader is defined to be the system class loader.
definePackage
getPackage
getPackages
findLibrary
setDefaultAssertionStatus
setPackageAssertionStatus
A subpackage of a package named p is any package whose name begins with «p.«. For example, javax.swing.text is a subpackage of javax.swing, and both java.util and java.lang.reflect are subpackages of java.
In the event that multiple package defaults apply to a given class, the package default pertaining to the most specific package takes precedence over the others. For example, if javax.lang and javax.lang.reflect both have package defaults associated with them, the latter package default applies to classes in javax.lang.reflect.
setClassAssertionStatus
If the named class is not a top-level class, this invocation will have no effect on the actual assertion status of any class.
clearAssertionStatus
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved. Use is subject to license terms. Also see the documentation redistribution policy.
- Что такое classical crossover
- Что такое classmates перевод