Перейти к контенту

ClassLoader в Java

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

Типы

  • Расширение ClassLoader (Extension).
  • Приложение или Система ClassLoader (Application or System).
  • Загрузчик ClassLoader (Bootstrap).

Расширение

Загружает расширения основных классов Java из библиотеки расширений JDK. Он является дочерним элементом Bootstrap и загружает расширения из каталога JRE / lib / text или любого другого каталога, указанного в системном свойстве java.ext.dirs.

 

Приложение или Система

Является дочерним по отношению к Extension. Этот тип загружает все классы уровня приложения, найденные в параметре командной строки -cp или в переменной среды CLASSPATH.

Загрузчик

Как все мы знаем, что 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:

  • Виртуальная машина проверяет, загружен ли класс или нет, всякий раз, когда она сталкивается с классом.
  • В случае, если класс загружен, JVM продолжает выполнение класса, но в сценарии, где класс не загружен, JVM просит подсистему ClassLoader загрузить этот конкретный класс. После этого подсистема ClassLoader передает управление приложению ClassLoader.
  • Затем приложение ClassLoader делегирует запрос расширению ClassLoader, которое затем передает запрос загрузчику ClassLoader.
  • Теперь загрузчик ClassLoader ищет в пути своем classpath, чтобы проверить, доступен ли класс или нет. Если класс доступен, он загружается, в противном случае запрос снова передается в расширение.
  • Расширение проверяет класс в расширении classpath. Если класс доступен, он загружается, в противном случае запрос снова передается в приложение ClassLoader.
  • Наконец, приложение ClassLoader ищет класс в пути к классам приложения. Если класс доступен, то загружается, иначе вы увидите исключение ClassNotFoundException.

Обратитесь к изображению ниже.
работа ClassLoader

Принцип видимости

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

Например, если у нас есть два класса: AB, предположим, что класс A загружается приложением ClassLoader, а класс B загружается расширением ClassLoader. Здесь классы A и B видны всем тем классам, которые загружены приложением ClassLoader, но класс B виден только тем классам, которые загружены расширением ClassLoader.

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

Методы

Вот несколько основных методов ClassLoader:

  • loadClass (имя строки, логическое разрешение);
  • defineClass();
  • findClass (Строковое имя);
  • Class.forName (имя строки, логическая инициализация, загрузчик ClassLoader);
  • GetParent();
  • getResource().

loadClass (имя строки, логическое разрешение)

Этот метод является точкой входа ClassLoader и используется для загрузки класса, на который ссылается JVM. Он принимает имя класса в качестве параметра. JVM вызывает метод loadClass() для разрешения ссылок на класс, устанавливая логическое значение true. Только если нам нужно определить, существует ли класс или нет, логический параметр имеет значение false.

public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {

defineClass()

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

protected final Class<?> defineClass(String name, byte[] b, int off, int len) throws ClassFormatError

findClass (Строковое имя)

Используется для поиска указанного класса. Таким образом, он просто находит класс с полностью определенным именем в качестве параметра, но не загружает класс. Метод loadClass() вызывает этот метод, если родительский ClassLoader не может найти запрошенный класс. Кроме того, если ни один из родителей ClassLoader не находит класс, реализация по умолчанию генерирует исключение ClassNotFoundException.

protected Class<?> findClass(String name) throws ClassNotFoundException

Class.forName (имя строки, логическая инициализация, загрузчик ClassLoader)

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

public static Class<?> forName(String name, boolean initialize, ClassLoader loader)throws ClassNotFoundException

GetParent()

Используется для возврата родительского ClassLoader для делегирования.

public final ClassLoader getParent()

getResource()

Пытается найти ресурс с заданным именем. Первоначально он делегирует запрос родительскому ClassLoader для ресурса. Если родительский объект имеет значение null, то ищется путь к ClassLoader, встроенному в JVM. Теперь, если это не удается, тогда метод вызовет findResource(String), чтобы найти ресурс, где имя ресурса указывается в качестве входных данных, которые могут быть как абсолютным, так и относительным путем к классу. Затем он возвращает объект URL для чтения ресурса или возвращает нулевое значение, если у ресурса нет достаточных прав для возврата ресурса или он не найден.

public URL getResource(String name)

Пользовательский

Встроенные ClassLoaders позаботятся о большинстве случаев, когда файлы уже находятся в файловой системе, но если вы хотите загрузить классы с локального жесткого диска, вам нужно использовать пользовательские ClassLoaders.

Чтобы создать собственный ClassLoader, вам нужно расширить класс ClassLoader и переопределить метод findClass():

package edureka;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

public class Sample extends ClassLoader {
	 
    @Override
    public Class findClass(String samplename) throws ClassNotFoundException {
        byte[] b = customLoadClassFromFile(samplename);
        return defineClass(samplename, b, 0, b.length);
    }
 
    private byte[] customLoadClassFromFile(String demofilename)  {
        InputStream inStream = getClass().getClassLoader().getResourceAsStream(
        		demofilename.replace('.', File.separatorChar) + ".class");
        byte[] buffer;
        ByteArrayOutputStream bStream = new ByteArrayOutputStream();
        int nextValue = 0;
        try {
            while ( (nextValue = inStream.read()) != -1 ) {
                bStream.write(nextValue);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        buffer = bStream.toByteArray();
        return buffer;
    }
}

Оцени статью

Средняя оценка / 5. Количество голосов:

Спасибо, помогите другим - напишите комментарий, добавьте информации к статье.

Или поделись статьей

Видим, что вы не нашли ответ на свой вопрос.

Помогите улучшить статью.

 

Пока нет комментариев.

Добавить комментарий

Ваш e-mail не будет опубликован.

СайдбарКомментарии (0)