JavaRush /Курсы /Java Core /Создание объекта. Порядок вызова конструкторов

Создание объекта. Порядок вызова конструкторов

Java Core
5 уровень , 5 лекция
Открыта

— Привет, Амиго! Сейчас я расскажу тебе о процессе создания объекта.

— А что там сложного, дядя Риша? Написал new имя класса, указал правильный конструктор и готово!

— Это так. Но что при этом происходит внутри объекта?

— А что там происходит?

— А вот что! Объект создается в несколько этапов.

1) Сначала выделяется память под все переменные – поля класса.

2) Затем идет инициализация базового класса.

3) Потом всем переменным присваиваются значения, если они указаны.

4) И наконец, вызывается конструктор.

— Выглядит не очень сложно: сначала переменные, затем конструктор.

— Давай посмотрим, как это будет работать на примере двух классов:

Код Описание
class Pet {
    int x = 5, y = 5; ←-
    int weight = 10; ←-

    Pet(int x, int y) {
        this.x = x; ←-
        this.y = y; ←-
    }
}
class Cat extends Pet {
    int tailLength = 8; ←-
    int age;
    Cat(int x, int y, int age) {
        super(x, y); ←-
        this.age = age; ←-
    }
}
Мы создали два класса: Pet(животное) и Cat(кот).

В классе Cat мы видим явный вызов конструктора базового класса.
Он всегда должен быть в первой строке конструктора.

Вот что произойдет после выделения памяти:
18 – вызов конструктора базового класса
3, 4 – инициализация переменных в Pet
8, 9 – отработает код конструктора Pet

далее начнется процесс инициализации класса Cat
14 – инициализация переменных в Cat
19 – отработает код конструктора Cat

public static void main(String[] args) {
    Cat cat = new Cat (50, 50, 5);
}

— Что-то немного запутанно. Почему так сложно?

— На самом деле не сложно, если знать что на самом деле происходит:
Если у класса нет ни одного конструктора, он будет создан автоматически.

Конструктор по умолчанию
class Cat {
    int x = 5;
    int y = 5;
}
class Cat {
    int x = 5;
    int y = 5;
 public Cat()   { }
}

Если не вызываешь конструктор базового класса, его вызов будет добавлен автоматически.

Вызов конструктора базового класса
class Pet {
    public String name;
}
class Pet extends Object {
    public String name;
    public Pet() {
        super();
    }
}
class Cat extends Pet {
    int x = 5;
    int y = 5;
}
class Cat extends Pet {
    int x = 5;
    int y = 5;
    public Cat() { super(); }
}

Инициализация переменных класса происходит в конструкторе.

Инициализация переменных класса
class Cat {
    int x = 5; int y = 5;
}
class Cat {
    int x;
    int y;
    public Cat() { super(); this.x = 5; this.y = 5; }
}
Как все это происходит на самом деле
class Pet {
    int x = 5, y = 5;
    int weight = 10;
    Pet(int x, int y) {
        this.x = x; this.y = y;
    }
}

class Cat extends Pet {
    int tailLength = 8;
    int age;
    Cat(int x, int y, int age) {
        super(x, y);
        this.age = age;
    }
}
class Pet extends Object {
    int x;
    int y;
    int weight;

    Pet(int x, int y) {
        //вызов конструктора базового класса
        super();
        //инициализация переменных
        this.x = 5; this.y = 5; this.weight = 10;
        //вызов кода конструктора
        this.x = x; this.y = y;
    }
}
class Cat extends Pet {
    int tailLength;
    int age;
    Cat(int x, int y, int age) {
        //вызов конструктора базового класса
        super(x, y);
        //инициализация переменных
        this.tailLength = 8;
        //вызов кода конструктора
        this.age = age;
    }
}
4
Задача
Java Core, 5 уровень, 5 лекция
Недоступна
Набираем код Ӏ Java Core: 5 уровень, 5 лекция
Иногда думать не надо, строчить надо! Как ни парадоксально звучит, порой пальцы «запоминают» лучше, чем сознание. И даже на втором квесте иногда полезно просто понабирать код. Вперёд!

— Теперь намного понятнее: сначала базовый класс, затем переменные вне конструктора, затем вызов кода конструктора.

— Молодец, Амиго, именно так!

Комментарии (234)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Anonymous #3554585 Уровень 68
25 августа 2025
Я не понял. Зачем предварительно инициализировать переменные, если конструктора по умолчанию всеравно нет? Или всетаки можно создать экземпляр класса с конструктором по умолчанию?
Anonymous #3585174 Уровень 33
19 августа 2025
Like
Anonymous #3497260 Уровень 27
19 января 2025
Чтобы стало понятнее, можно почитать ещё тут: https://github.com/n-bykoff/AarexerJBook/blob/master/classes/order_of_loading.md
NikitaMorozka Уровень 38
20 ноября 2024
Британским ученым не хватило финансирования, и они вынуждены были досрочно прекратить опасный научный эксперимент «Сколько денег может потратить женщина».
Алексей Уровень 1
5 октября 2024
ну, как бы не очень сложно.
{Java_Shark} Уровень 36
4 октября 2024
++
Bohdan Уровень 7
3 июня 2024
А это довольно интересно. Теперь понятно почему final переменной можно присвоить значение только напрямую или через конструктор (по сути один и тот же принцип/операция)
SomeBody098 Уровень 51
27 мая 2024
Vladislav Gorokhov Уровень 32
15 февраля 2024
А про статический блок и динамический блок нам когда расскажут? 😐
Anonymous #3390940 Уровень 38
27 января 2024
Здесь описано лучше - Порядок действий при создании объекта По шагам: 1. инициализация статических переменные класса родителя (базового класса) 2. инициализация статических переменные класса потомка 3. инициализация НЕстатических переменных класса родителя (базового класса) 4. вызов конструктора класса родителя (базового класса) - (с базовым классом закончили) - 5. инициализация НЕстатических полей класса потомка 6. вызов конструктора класса потомка
Dmytrii Уровень 40
1 марта 2026
если точнее, то так

1. static field parent
2. static { } parent
3. static field child
4. static { } сhild
5. non static field parent
6. non static { } parent
7. constructor parent
8. non static field child
9. non static { } child
10. constructor child