← Назад к вопросам

Что делает ClassLoader во время компиляции?

1.3 Junior🔥 171 комментариев
#ORM и Hibernate#Spring Boot и Spring Data#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

ClassLoader во время компиляции и выполнения

Важно уточнить: ClassLoader НИЧЕГО не делает во время компиляции. Компиляция — это работа javac (Java Compiler), а ClassLoader работает только во время выполнения программы (runtime).

Процесс компиляции

Во время компиляции (когда вы вводите javac MyClass.java):

  1. javac читает исходный код .java
  2. javac проверяет синтаксис и типы
  3. javac генерирует файл .class (байт-код)

КлассLoaders на этом этапе НЕ участвуют.

Что делает ClassLoader во время выполнения

ClassLoader — это компонент Java Runtime Environment (JRE), который:

// Пример запуска программы
java MyClass  // JVM запускается, ClassLoader загружает классы

Три основных функции ClassLoader

1. Loading (Загрузка)

КлассLoaders загружают .class файлы из:

  • Файловой системы
  • JAR архивов
  • Сети
  • Памяти
// Явная загрузка класса
Class<?> clazz = ClassLoader.getSystemClassLoader()
    .loadClass("com.example.MyClass");

2. Linking (Связывание)

После загрузки выполняется линковка:

  • Verification (Проверка) — проверка корректности байт-кода
  • Preparation (Подготовка) — выделение памяти для статических переменных
  • Resolution (Разрешение) — преобразование символических ссылок в реальные адреса
public class Example {
    static int x = 100;  // При линковке выделяется память
    
    public void test() {
        System.out.println(x);  // Разрешение ссылки на x
    }
}

3. Initialization (Инициализация)

Выполнение статических инициализаторов и присвоение начальных значений:

public class Config {
    static {
        System.out.println("Static initializer executed");
    }
    
    static int config = loadConfig();  // Выполняется при инициализации
    
    static int loadConfig() {
        return 42;
    }
}

Иерархия ClassLoaders

В Java существует три уровня ClassLoaders:

// 1. Bootstrap ClassLoader (встроен в JVM)
// Загружает классы из rt.jar (java.lang, java.util и т.д.)

// 2. Extension ClassLoader (загружает расширения)
// Загружает классы из директории ext

// 3. Application ClassLoader (ваш класслоадер)
// Загружает классы из CLASSPATH

public class ClassLoaderHierarchy {
    public static void main(String[] args) {
        // Получить Application ClassLoader
        ClassLoader appLoader = ClassLoader.getSystemClassLoader();
        System.out.println("App: " + appLoader);
        
        // Родительский (Extension)
        System.out.println("Ext: " + appLoader.getParent());
        
        // Прародительский (Bootstrap) - null, потому что встроен в JVM
        System.out.println("Bootstrap: " + appLoader.getParent().getParent());
    }
}

Принцип Delegation (Делегирование)

КлассLoaders работают по принципу Delegation Model:

Application ClassLoader
       ↓
Если не найден, спрашивает у
       ↓
Extension ClassLoader
       ↓
Если не найден, спрашивает у
       ↓
Bootstrap ClassLoader
       ↓
Если он не найдёт → ClassNotFoundException
public class LoaderExample {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> stringClass = Class.forName("java.lang.String");
        System.out.println(stringClass.getClassLoader());  // null (Bootstrap)
        
        Class<?> myClass = Class.forName("com.example.MyClass");
        System.out.println(myClass.getClassLoader());  // Application ClassLoader
    }
}

Кастомный ClassLoader

Вы можете создать собственный ClassLoader:

public class CustomClassLoader extends ClassLoader {
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] classData = loadClassBytes(name);
        return defineClass(name, classData, 0, classData.length);
    }
    
    private byte[] loadClassBytes(String name) {
        // Загрузить .class файл или получить из сети
        return new byte[0];
    }
}

Практическое применение

Сегодня ClassLoaders используются для:

  • OSGi контейнеры — управление модулями
  • Веб-фреймворки (Spring, Tomcat) — изоляция приложений
  • IDE и сборщики — горячая перезагрузка классов
  • Динамические прокси и инструментирование кода

Итоговое уточнение

ЭтапКомпонентЧто происходит
Компиляцияjavac.java.class байт-код
Runtime (загрузка)ClassLoaderЗагрузка .class файлов
Runtime (выполнение)JVMВыполнение байт-кода

Вывод: ClassLoader работает только во время выполнения, не во время компиляции.