Что делает ClassLoader во время компиляции?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
ClassLoader во время компиляции и выполнения
Важно уточнить: ClassLoader НИЧЕГО не делает во время компиляции. Компиляция — это работа javac (Java Compiler), а ClassLoader работает только во время выполнения программы (runtime).
Процесс компиляции
Во время компиляции (когда вы вводите javac MyClass.java):
- javac читает исходный код
.java - javac проверяет синтаксис и типы
- 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 работает только во время выполнения, не во время компиляции.