Ответ
Инициализационные блоки в Java — это блоки кода без имени, выполняемые для инициализации полей класса. Они бывают двух видов: статические и нестатические.
1. Нестатический блок инициализации
- Выполняется перед каждым вызовом конструктора при создании объекта.
- Используется для инициализации нестатических полей сложной логикой.
- В одном классе может быть несколько блоков — они выполняются в порядке объявления.
public class MyClass {
private int x;
private List<String> list;
// Нестатический блок
{
x = 10;
list = new ArrayList<>();
list.add("First"); // Сложная логика инициализации
System.out.println("Нестатический блок выполнен. x = " + x);
}
public MyClass() {
System.out.println("Конструктор выполнен.");
}
}
// Вывод при new MyClass():
// Нестатический блок выполнен. x = 10
// Конструктор выполнен.
2. Статический блок инициализации
- Выполняется один раз при первой загрузке класса в JVM (перед созданием любого объекта или обращением к статическим членам).
- Используется для инициализации статических полей сложной логикой.
public class DatabaseConfig {
private static Properties config;
// Статический блок
static {
config = new Properties();
try (InputStream is = DatabaseConfig.class.getResourceAsStream("/db.properties")) {
config.load(is); // Загрузка конфигурации из файла
System.out.println("Статический блок: конфиг загружен.");
} catch (IOException e) {
throw new RuntimeException("Ошибка загрузки конфига", e);
}
}
public static String getUrl() {
return config.getProperty("db.url");
}
}
Порядок выполнения инициализации:
- Статические поля и блоки класса (в порядке объявления).
- Нестатические поля и блоки объекта (в порядке объявления).
- Конструктор объекта.
Ответ 18+ 🔞
А, инициализационные блоки, ёпта! Это ж как те самые закулисные рабочие, которые всё подготавливают, пока актёры-конструкторы на сцену не вышли. Суть проще пареной репы, но народ иногда путается, будто в тёмной комнате ищет чёрную кошку, которой там нет.
Смотри, их всего два вида, и они как близнецы, но один — статик, вечный и одинокий, а второй — нестатик, шустрый и плодовитый.
Первый тип — нестатический блок инициализации.
Этот пацан работает на каждый новый объект, прям как заведённый. Создаёшь ты новый экземпляр — а он уже тут как тут, выскакивает прямо перед конструктором и начинает свою магию. Идеален, когда тебе надо не просто x = 5; присвоить, а там список накрутить, файл прочитать или ещё какую хитрожопую логику для полей запилить. Таких блоков можешь наставить несколько — отработают они строго по очереди, как в очереди за блатными пайками.
public class МояХата {
private int водка;
private List<String> закуски;
// Вот он, нестатический блок
{
водка = 100; // грамм, ясное дело
закуски = new ArrayList<>();
закуски.add("Селедочка"); // Сложная жизненная инициализация
System.out.println("Нестатический блок: водка налита, закуска готова. Водка = " + водка);
}
public МояХата() {
System.out.println("Конструктор: можно садиться жрать.");
}
}
// Создаём объект (new МояХата()) и видим:
// Нестатический блок: водка налита, закуска готова. Водка = 100
// Конструктор: можно садиться жрать.
Второй тип — статический блок инициализации.
А вот это уже серьёзный дядька. Он выполняется всего один раз, когда класс грузится в память, и всё. До первого объекта, до первого статического вызова — он уже всё сделал. Типичное применение — загрузка конфигов, установка драйверов, всё такое глобальное и тяжёлое. Сделал и забыл, как страшный сон.
public class КонфигБазы {
private static Properties настройки;
// Статический блок, один на всю жизнь класса
static {
настройки = new Properties();
try (InputStream is = КонфигБазы.class.getResourceAsStream("/db.properties")) {
настройки.load(is); // Тянем конфиг из файла
System.out.println("Статический блок: конфиг загружен, можно работать.");
} catch (IOException e) {
throw new RuntimeException("Ошибка загрузки конфига, всё пропало!", e);
}
}
public static String getUrl() {
return настройки.getProperty("db.url");
}
}
А теперь, блядь, порядок, чтобы не было каши в голове:
- Сначала статика. Все статические поля и блоки класса — раз и навсегда, по очереди.
- Потом экземпляр. Для каждого нового объекта — все его нестатические поля и блоки, тоже по порядку.
- И только в конце, как вишенка на торте, вызывается конструктор объекта.
Вот и вся философия. Не перепутай, а то получится как в той поговорке: статику в конструктор, нестатику в статик — и будет тебе, сука, NullPointerException вместо ужина.