tg-me.com/javatg/1825
Create:
Last Update:
Last Update:
☕ Вопрос с собеседования: Статический блок и порядок инициализации
🔍 Условие:
Что выведет следующий код и почему?
public class InitializationPuzzle {
static {
System.out.println("Static block 1");
}
public static void main(String[] args) {
Child.doSomething();
}
}
class Parent {
static {
System.out.println("Parent static block");
}
}
class Child extends Parent {
static {
System.out.println("Child static block");
}
static void doSomething() {
System.out.println("Child method");
}
}
❓ Вопрос:
Какой будет порядок вывода? Почему результат может удивить даже опытных Java-разработчиков?
🔍 Разбор:
✅ Что происходит по шагам:
1️⃣ При запуске программы сначала загружается класс `InitializationPuzzle`. Его статический блок выполняется сразу:
Static block 1
2️⃣ Далее вызывается
Child.doSomething()
. Теперь происходит инициализация класса `Child`. В Java при инициализации класса-потомка сначала загружается родительский класс, если он ещё не был загружен.- Инициализация
Parent
:
Parent static block
- Инициализация
Child
:
Child static block
3️⃣ Наконец выполняется метод
doSomething()
:
Child method
---
✅ Ожидаемый полный вывод:
Static block 1
Parent static block
Child static block
Child method
💥 Подвох:
• Многие разработчики думают, что раз
doSomething()
просто статический метод, может выполниться только он. • Однако Java гарантирует, что перед выполнением любого статического метода класс будет полностью инициализирован.
• Также важно помнить, что при инициализации класса наследника сначала выполняются статические блоки родителя.
🛡️ Лайфхак:
Если вы хотите убедиться, что родительский класс не инициализируется при доступе к статическим полям/методам потомка, нужно использовать константы (static final), которые компилируются напрямую в байткод и не требуют загрузки класса.
✅ Вывод:
• Java строго инициализирует классы в порядке наследования перед вызовом любых статических методов.
• Даже вызов одного «безопасного» статического метода потомка затянет за собой загрузку родителя.
• Такие задачи хорошо проверяют понимание механизма класслоадеров и инициализации классов в JVM.
💡 Бонус-вопрос:
Что изменится, если вы замените
doSomething()
на чтение static final поля в Child
? Будет ли тогда инициализирован Parent
?@javatg
BY Java
Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283
Share with your friend now:
tg-me.com/javatg/1825