Что такое class loader и как работает делегирование загрузки классов?
- Зачем загрузчики классов сначала делегируют загрузку родителю?
- Зачем загрузчики классов сначала делегируют загрузку родителю (parent-first)?
ClassLoader находит байт-код и превращает его в класс. Иерархия: Bootstrap (ядро JDK) → Platform (модули платформы) → Application (classpath). Модель parent-first: запрос сначала идёт к родителю, и только если тот не нашёл — загрузчик ищет сам.
- Защита: свой java.lang.String в classpath не подменит системный
- Класс в JVM определяется парой «полное имя + загрузчик»
- Исключения: сервлет-контейнеры грузят классы приложения первыми (child-first)
А ещё Утечка загрузчика — источник OutOfMemoryError: Metaspace при передеплое
Подробно
Иерархия загрузчиков (Java 9+):
- Bootstrap — встроенный в JVM, грузит
java.baseи ядро; - Platform — остальные модули Java SE и JDK;
- Application (System) — классы из classpath и module path приложения.
Делегирование. loadClass сначала проверяет, не загружен ли класс, затем просит родителя, и только при неудаче вызывает свой findClass. Зачем:
- безопасность — классы платформы всегда приходят от доверенного загрузчика, подменить
java.lang.Stringнельзя; - единственность — базовый класс загружается один раз, а не каждым загрузчиком отдельно.
Идентичность класса. Один и тот же байт-код, загруженный двумя загрузчиками, — два разных класса. Отсюда «ClassCastException: Foo cannot be cast to Foo». На этом же построена изоляция: плагины и веб-приложения используют разные версии одной библиотеки.
Отступления от parent-first: сервлет-контейнеры (Tomcat) сначала ищут в WEB-INF приложения, чтобы его библиотеки не перекрывались серверными; OSGi и системы плагинов строят граф загрузчиков. Для SPI используют контекстный загрузчик потока (Thread.getContextClassLoader).
Загрузка ленивая: класс загружается и инициализируется при первом активном использовании.
Что хотят услышать
- Иерархия загрузчиков.
- Parent-first и его цель.
- Идентичность класса.
- Где правило нарушают.
Частые ошибки
- Не знать, что класс определяется и загрузчиком.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Загрузчик сначала ищет класс сам, а к родителю обращается, только если не нашёл
- ✓Parent-first: запрос сначала уходит родителю, и только если тот не нашёл, загрузчик ищет сам
- ✗Все классы грузит один загрузчик
- ✗Класс определяется только полным именем, поэтому два загрузчика всегда дают один и тот же класс
Что спросят дальше
- Что такое metaspace?
- Почему два одинаковых класса из разных classloader несовместимы?
- Почему контейнеры приложений отступают от parent-first?
- Когда класс считается инициализированным?
Разбор темы
- Загрузка классов и class loaders
Жизненный цикл класса (loading/linking/initialization), иерархия загрузчиков с делегированием, триггеры инициализации и изоляция.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.