0Pricing
Java Academy · Урок

Иерархия ClassLoader и пользовательские загрузчики

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

«Иерархия ClassLoader и пользовательские загрузчики» — бесплатный урок Java Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.

Иерархия ClassLoader

JVM использует иерархию ClassLoader. У каждого загрузчика есть родитель; прежде чем загрузить класс самостоятельно, он делегирует загрузку родителю (модель делегирования сначала родителю).

Загрузчик Bootstrap

Загрузчик Bootstrap загружает основные классы JDK (java.lang.*, java.util.*). Он реализован в машинном коде и не имеет родительского Java-загрузчика; getParent() возвращает null.

ClassLoader cl = String.class.getClassLoader();
System.out.println(cl); // null (bootstrap ClassLoader)

Платформенный ClassLoader (Java 9+)

Платформенный ClassLoader (ранее ClassLoader расширений) загружает модули из JDK, не входящие в начальный набор (java.sql, java.xml и т. д.). Его родитель — загрузчик Bootstrap.

ClassLoader platform = ClassLoader.getPlatformClassLoader();
System.out.println(platform.getClass().getName());
// jdk.internal.loader.ClassLoaders$PlatformClassLoader

ClassLoader приложения (системный)

ClassLoader приложения загружает классы приложения из пути классов (-cp / CLASSPATH). Его родитель — платформенный ClassLoader. Это загрузчик по умолчанию для пользовательского кода.

ClassLoader app = ClassLoader.getSystemClassLoader();
System.out.println(app.getClass().getName());
// jdk.internal.loader.ClassLoaders$AppClassLoader

Делегирование сначала родителю

При загрузке com.example.MyService AppClassLoader сначала обращается к своему родителю (платформенному), который обращается к Bootstrap. Только если ни один из родителей не может загрузить класс, дочерний загрузчик пытается загрузить его самостоятельно.

Идентичность классов и ClassLoaders

Два класса с одним именем, загруженные разными ClassLoaders, считаются разными типами. Приведение одного к другому вызывает ClassCastException — это важно в системах плагинов и OSGi.

// Loaded by two different loaders → different Class objects
Class<?> c1 = loader1.loadClass("com.example.Plugin");
Class<?> c2 = loader2.loadClass("com.example.Plugin");
System.out.println(c1 == c2); // false!

Создание собственного ClassLoader

Расширьте ClassLoader и переопределите findClass(String name). Прочитайте байт-код из пользовательского источника (зашифрованного JAR, сети или базы данных) и вызовите defineClass.

public class EncryptedClassLoader extends ClassLoader {
    public EncryptedClassLoader(ClassLoader parent) { super(parent); }
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] bytes = decrypt(readBytecodeFromVault(name));
        return defineClass(name, bytes, 0, bytes.length);
    }
}

URL ClassLoader: загрузка из JAR-файлов

URLClassLoader загружает классы из списка URL (путей к файлам или HTTP-адресов). Это полезно для систем плагинов, которые добавляют JAR-файлы во время выполнения.

URL[] urls = { new File("plugins/my-plugin.jar").toURI().toURL() };
try (URLClassLoader loader = new URLClassLoader(urls, getClass().getClassLoader())) {
    Class<?> cls = loader.loadClass("com.example.PluginImpl");
    Plugin plugin = (Plugin) cls.getDeclaredConstructor().newInstance();
    plugin.start();
}

Закрытие ClassLoaders

Всегда закрывайте URLClassLoader после завершения работы — он удерживает JAR-файлы открытыми. После закрытия JAR-файлы можно удалить или обновить. Используйте конструкцию try с ресурсами.

Делегирование сначала дочернему загрузчику (изолированная загрузка)

Некоторые контейнеры (Tomcat, Spring Boot с JAR-файлом, содержащим зависимости) инвертируют иерархию: дочерний загрузчик пытается загрузить класс первым и обращается к родителю только при отсутствии класса. Это изолирует версии библиотек между веб-приложениями.

Утечки ClassLoader

Загрузчик классов освобождается сборщиком мусора только тогда, когда недоступен ни один загруженный им класс. Статические поля, удерживающие объекты из загруженного класса, не дают загрузчику освободиться — это распространённая утечка при переразвертывании приложения.

Быстрая проверка

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

Итоги

Трёхуровневая иерархия: Bootstrap → Platform → Application. Делегирование сначала родителю предотвращает дублирование классов. Пользовательские загрузчики переопределяют findClass. Используйте URLClassLoader для систем плагинов. Закрывайте загрузчики, чтобы предотвратить утечки.

Часто задаваемые вопросы

Урок «Иерархия ClassLoader и пользовательские загрузчики» бесплатный?

Да — полный текст урока «Иерархия ClassLoader и пользовательские загрузчики» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.

Чему я научусь в уроке «Иерархия ClassLoader и пользовательские загрузчики»?

Поймите работу загрузчиков классов начальной загрузки, платформы и приложения и напишите собственный ClassLoader. Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Java Academy?

Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Иерархия ClassLoader и пользовательские загрузчики»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Java Academy?

Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Этапы загрузки классов: загрузка, связывание, инициализация
  2. Иерархия ClassLoader и пользовательские загрузчики
  3. Просмотр байткода с помощью javap
  4. JIT-компиляция и многоуровневая компиляция
← Назад к Java Academy