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

Открыта

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

— А что там сложного, дядя Риша? Написал 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 лекция
Иногда думать не надо, строчить надо! Как ни парадоксально звучит, порой пальцы «запоминают» лучше, чем сознание. И даже на втором квесте иногда полезно просто понабирать код. Вперёд!
Комментарии (122)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий вы должны авторизоваться
dolcom17 уровень, Самара
29 июля, 09:14
3) Потом всем переменным присваиваются значения, если они указаны.

4) И наконец, вызывается конструктор.
Исходя из блоков "Как всё происходит на самом деле", вероятнее всего порядок должен быть такием:
3) Потом вызывается конструктор.

4) И, наконец, в конструкторе всем переменным присваиваются значения, если они указаны.
В противном случае, непонятно для чего вызывается конструктор, если переменные и без него инициализируются
Иван16 уровень, Москва
19 июля, 14:26
Для таких же как и я..:) Если кто до сих пор не понимает, что такое конструктор и зачем он нужен или отвечает на этот вопрос так: ээээ, ну this.названиеПеременной, что бы создаваемому объекту, 100% присвоили какие то значения. Спасибо! Вот супер статья, на эту тему: http://developer.alexanderklimov.ru/android/java/constructor.php#:~:text=%D0%9A%D0%BE%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D0%BE%D1%80%20%2D%20%D1%8D%D1%82%D0%BE%20%D1%81%D0%BF%D0%B5%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9%20%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%2C%20%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D0%B9,%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%B0%20%D0%BF%D1%80%D0%B8%20%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B8%20%D0%B5%D0%B3%D0%BE%20%D1%8D%D0%BA%D0%B7%D0%B5%D0%BC%D0%BF%D0%BB%D1%8F%D1%80%D0%B0.&text=%D0%9F%D0%BE%20%D1%81%D1%83%D1%82%D0%B8%20%D0%BA%D0%BE%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D0%BE%D1%80%20%D0%BD%D1%83%D0%B6%D0%B5%D0%BD%20%D0%B4%D0%BB%D1%8F,%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%20%D0%BD%D0%B5%D0%BF%D0%BE%D1%81%D1%80%D0%B5%D0%B4%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%20%D0%B2%D0%BE%20%D0%B2%D1%80%D0%B5%D0%BC%D1%8F%20%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F.
Иван16 уровень, Москва
19 июля, 14:21
А в чем суть? в том, что инициализация переменных происходит в конструкторе, даже если мы это не пропишем?
Mercury20 уровень, Киев
13 июля, 11:10
https://www.youtube.com/watch?v=cla2N9B88rs офигенное видео о порядке вызовов переменных и конструкторов в родительских и дочерних классах
Евгений Хайретдинов15 уровень, Нефтекамск
11 июля, 12:03
Долго втыкал в это - int tailLength = 8. Это в каких единицах измерения? В одних единицах хвост слишком короткий, в других - слишком длинный. Измерил хвост у своего - 24 см.
Глеб18 уровень, Киев
12 июля, 04:06
Может у них котёнок маленький
Kirill Gorbunov17 уровень, Москва
17 июля, 13:26
В дюймах отлично подходит
Andrey15 уровень, Одесса
14 июня, 12:44
Как же напрягяет валидатор в упраженния "Набираем код" Набрал всё корректно, но или одна пустая строка, или табуляция вместо пробела, или ещё какая то мелочь которая ну абсолютно никак не влияет на код не проходят валидатор. Dear @Validator, flease fix this stupid bug!
Alexander Korzhov18 уровень, Минск
2 июля, 21:06
с зажатым альтом можно копировать код в таких заданиях)
AndyS16 уровень, Москва
8 июля, 01:26
Ctrl-C из блока выше с примером этого задания. Ctrl-V в том месте, где надо перепечатать код. Всё.
Артур 19 уровень, Ташкент
14 июня, 10:10
разве в последнем примере справа строки 12, 13, 14 обращение для инициализации не через super должно быть? super.x = 5; super.y = 5; super.weight = 10;
Антоний Шаламов19 уровень, Хабаровск
18 июня, 09:44
Это не тот код, который писать надо, это демонстрация, как это работает под капотом. Во вторых - у класса Pet родитель Object, а там полей нет
Артур 19 уровень, Ташкент
18 июня, 13:33
Спасибо! Разобрался
Dmitry23 уровень, Минск
9 мая, 11:21
класс Дед (){ public дед (){sout ("Я твой дед")} // в конструкторе } class Папа() extends Дед{ public Папа (){sout (" Я твой папа")} } class Внук() extends Папа{ public Внук (){sout( "Как говорил мой дед - я твой дед")} } ___________ метод мэин: Внук внук = new Внук() ________________ на экран выходит: Я твой дед Я твой папа Как говорил мой дед - я твой дед.
Юрий17 уровень, Москва
4 июня, 21:00
Вот так понятнее в пару строк)))
ReJuFe25 уровень
2 мая, 09:41
Может кто-то обьяснить зачем знать это? Как может пригодиться порядок инициализации при решении задач?
Drew19 уровень, Москва
11 мая, 14:44
Во многой мудрости много печали; и кто умножает познания, умножает скорбь(Соломон Дядя Риша)
Alexandr Mihailovich20 уровень, Kursk
26 мая, 18:54
это очень хорошо объясняет наследование и полиморфизм
MAX16 уровень, Киров
5 июня, 23:35
Creed
Алексей20 уровень, Минск
6 июня, 03:47
Последовательный вызов конструкторов вверх по иерархии наследования при создании нового объекта называется "формирование цепочки конструкторов" То, что это такое и как выполняется - очень важно для понимания. Если сейчас не вкурить эту тему, то когда начнется изучение сериализации/десериализацию объектов - будут страдания.
Igor Manziy19 уровень, Киев
21 марта, 10:07
Обьясните такой момент, ''2) Затем идет инициализация базового класса." 1). Когда идет инициализация,обьект базового класса тоже создается?Ведь в java все обьекты,может ли произойти инициализация без создания обьекта? 2). Если все же при инициализации обьект создается, то вопрос следующий - а если родитель является абстрактным классом?Ведь как мы знаем нельзя создать обьект абстрактного класа. А есть ли в абстрактном класе вообще конструкторы? Вообщем если кто то сможет это все разложить по полочкам, буду очень признателен
Badger22 уровень, Киев
21 марта, 16:15
На сколько я изучил материал, то: Ответ на первый вопрос - объект базового класса не создается, просто выполняется конструктор инициализируя поля, если они есть. Один new, один объект. Второй вопрос - опять же, объект не создается и создать объект абстрактного класса нельзя. А вот конструктор у абстрактного класса есть и если вы его не напишите, то компилятор его добавит сам, как и в обычном классе. Зачем ему конструктор раз нельзя создать объект? Конструктор можно вызывать из наследника, получив доступ к полям класса.