JavaRush /Курсы /JAVA 25 SELF /Инициализация объекта: порядок инициализации

Инициализация объекта: порядок инициализации

JAVA 25 SELF
14 уровень , 5 лекция
Открыта

1. Порядок инициализации объекта в Java: кто первый, кто последний?

Создание объекта в Java — это не просто «выделить память и записать туда значения». Это целый ритуал с чётким порядком действий. Если представить процесс инициализации как запуск ракеты, то у каждой ступени есть своё строгое место.

Когда вы пишете:

Person vasya = new Person("Вася", 30);

Java выполняет следующие шаги:

  1. Выделяет память под объект и присваивает всем полям значения по умолчанию.
  2. Выполняет явные инициализации полей (если вы указали значения прямо при объявлении).
  3. Выполняет все нестатические (обычные) блоки инициализации — в том порядке, в каком они написаны в классе.
  4. Выполняет тело конструктора, который вы вызвали через new.

Давайте рассмотрим каждый шаг подробно.

2. Инициализация полей

Значения по умолчанию

Когда объект только-только создаётся (ещё до того, как вы что-то явно присвоили), все его поля получают значения по умолчанию:

Тип поля Значение по умолчанию
int, short, byte, long
0
float, double
0.0
boolean
false
char
'\u0000' (нулевой символ)
Ссылочные типы (String, другие объекты)
null

Явная инициализация

Если вы при объявлении поля сразу задаёте ему значение, это значение будет установлено после значений по умолчанию, но до выполнения конструктора.

public class Person {
    private String name = "Безымянный";
    private int age = 18;
}

Если вы создадите объект через пустой конструктор, эти значения останутся. Если через конструктор с параметрами — скорее всего, они будут переопределены.

3. Блоки инициализации: зачем они нужны и как работают

В Java можно объявлять так называемые нестатические (обычные) блоки инициализации. Они выполняются каждый раз при создании объекта, сразу после инициализации полей, но до конструктора.

Синтаксис:

public class Person {
    {
        System.out.println("Выполняется нестатический блок инициализации!");
    }
}

Если в классе несколько таких блоков, они выполняются в том порядке, в каком написаны.

Пример с несколькими блоками

public class Person {
    private String name = "Безымянный";

    {
        System.out.println("Блок 1: name = " + name);
        name = "Загадка";
    }

    {
        System.out.println("Блок 2: name = " + name);
    }

    public Person() {
        System.out.println("Конструктор: name = " + name);
    }
}

Если создать объект:

Person p = new Person();

Вывод будет:

Блок 1: name = Безымянный
Блок 2: name = Загадка
Конструктор: name = Загадка

Для чего нужны блоки инициализации?

В реальной жизни блоки инициализации используются редко. Обычно всё, что можно сделать в блоке, можно сделать либо при объявлении поля, либо в конструкторе. Но иногда (например, если у вас несколько конструкторов, а часть логики инициализации должна быть общей для всех) блоки инициализации могут быть удобны.

4. Конструктор: финальный аккорд инициализации

После того как все поля получили значения (по умолчанию или явно), и отработали все блоки инициализации, вызывается конструктор — тот самый, который вы указали после new.

В конструкторе вы обычно задаёте итоговые значения полей, принимаете параметры и выполняете другую инициализацию, которая зависит от входных данных.

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        System.out.println("Конструктор: name = " + name + ", age = " + age);
        this.name = name;
        this.age = age;
    }
}

5. Демонстрация полного порядка инициализации

Давайте напишем класс, который явно покажет, в каком порядке происходит инициализация.

public class Person {
    private String name = "Безымянный";
    private int age = 18;

    {
        System.out.println("Блок инициализации: name = " + name + ", age = " + age);
        age = 21;
    }

    public Person() {
        System.out.println("Конструктор без параметров: name = " + name + ", age = " + age);
    }

    public Person(String name, int age) {
        System.out.println("Конструктор с параметрами: name = " + name + ", age = " + age);
        this.name = name;
        this.age = age;
    }

    public void printInfo() {
        System.out.println("Person: name = " + name + ", age = " + age);
    }
}

И теперь в нашем основном классе (например, Main):

public class Main {
    public static void main(String[] args) {
        System.out.println("Создаём объект p1:");
        Person p1 = new Person();
        p1.printInfo();

        System.out.println("\nСоздаём объект p2:");
        Person p2 = new Person("Петя", 30);
        p2.printInfo();
    }
}

Вывод будет примерно такой:

Создаём объект p1:
Блок инициализации: name = Безымянный, age = 18
Конструктор без параметров: name = Безымянный, age = 21
Person: name = Безымянный, age = 21

Создаём объект p2:
Блок инициализации: name = Безымянный, age = 18
Конструктор с параметрами: name = Безымянный, age = 21
Person: name = Петя, age = 30

Обратите внимание: в конструктор с параметрами значения полей ещё старые (те, что после блока инициализации), а уже после конструктора поля получают финальные значения.

6. Диаграмма порядка инициализации

Вот небольшая схема (блок-схема) для визуализации:

flowchart TD
    A[Выделение памяти, значения по умолчанию] --> B[Явная инициализация полей]
    B --> C[Выполнение нестатических блоков инициализации]
    C --> D[Выполнение конструктора]
    D --> E[Объект готов к использованию]

7. Особенности и нюансы

Статические поля и статические блоки

В этой лекции мы говорим только о нестатических (обычных) полях и блоках. Статические поля и статические блоки инициализируются один раз при загрузке класса, а не при каждом создании объекта. Подробнее о них поговорим в темах по инкапсуляции.

Когда что инициализируется?

  • Поля — при каждом создании объекта.
  • Блоки инициализации — при каждом создании объекта.
  • Статические поля и блоки — только один раз при загрузке класса.

Можно ли обращаться к полям в блоках инициализации?

Да, можно! Но важно помнить, что если поле объявлено ниже блока, оно уже существует, а если вы обратитесь к нему до явной инициализации, получите значение по умолчанию.

8. Типичные ошибки при инициализации объектов

Ошибка №1: Ожидание, что поля проинициализируются до их объявления.
В Java порядок объявления полей и блоков инициализации в классе имеет значение. Если вы в блоке инициализации обращаетесь к полю, которое объявлено ниже, оно уже существует, но ещё не проинициализировано явно — будет значение по умолчанию.

Ошибка №2: Дублирование инициализации в блоках и конструкторах.
Новички часто повторяют одну и ту же логику и в блоке, и в конструкторе. Лучше использовать или блок, или конструктор, или вызывать один конструктор из другого через this(...).

Ошибка №3: Ожидание, что статические поля инициализируются при каждом создании объекта.
Статические поля и блоки работают иначе — они инициализируются только один раз при загрузке класса.

Ошибка №4: Использование неинициализированных ссылочных полей.
Если вы забыли явно инициализировать ссылочное поле (например, String name;), то оно будет равно null до тех пор, пока вы не присвоите ему значение явно в блоке инициализации или в конструкторе.

1
Задача
JAVA 25 SELF, 14 уровень, 5 лекция
Недоступна
Наблюдение за появлением виртуальных существ
Наблюдение за появлением виртуальных существ
1
Задача
JAVA 25 SELF, 14 уровень, 5 лекция
Недоступна
Стандартизация новых книг в издательстве
Стандартизация новых книг в издательстве
1
Задача
JAVA 25 SELF, 14 уровень, 5 лекция
Недоступна
Отслеживание начала сборки каждой машины на заводе
Отслеживание начала сборки каждой машины на заводе
1
Задача
JAVA 25 SELF, 14 уровень, 5 лекция
Недоступна
Путь студента к итоговой оценке
Путь студента к итоговой оценке
1
Опрос
Классы и конструкторы, 14 уровень, 5 лекция
Недоступен
Классы и конструкторы
Классы и конструкторы
Комментарии (4)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Iskander Уровень 16
19 января 2026
Последний вопрос в опросе как-то двояко сформулирован (Что произойдет, если в блоке инициализации обратиться к полю, объявленному ниже блока?) Я так понимаю идет обращение к полю, которого вообще нет еще. Это поле появится позже.
Александр Уровень 50
19 октября 2025
В итоговом опроснике есть такой вопрос: "Что произойдет, если обратиться к полю объекта без использования ключевого слова new?" Чушь какая-то. Как вообще может выглядеть обращение к полю с помощью ключевого слова new? Прошу пояснить.
Xaxatumba Уровень 38
9 ноября 2025

String firstName = new Person().name;
Александр Уровень 50
19 октября 2025
Пункт 5. Посмотрел, засомневался, проверил. В лекции ошибка.

public Person(String name, int age) {
        System.out.println("Конструктор с параметрами: name = " + name + ", age = " + " + age);
        this.name = name;
        this.age = age;
    }
Здесь выводится в консоль значение локальных переменных, которые были получены в качестве аргументов (локальные переменные затеняют поля класса). Соответственно, вывод в консоль такой: Конструктор с параметрами: name = Петя, age = 30 А обратиться из объекта к его собственным полям нужно с помощью ключевого слова this

System.out.println("Конструктор с параметрами: name = " + this.name + ", age = " + " + this.age);