"Olá, amigo! Agora vou contar como os objetos são criados."

"O que há de tão complicado nisso, tio Rishi? Você escreve new e o nome da classe, indica o construtor correto e pronto!"

"Isso é verdade. Mas o que acontece dentro do objeto quando você faz isso?"

"O que acontece?"

"Isto é o que acontece: o objeto é criado em vários estágios."

1)  Primeiro, a memória é alocada para todas as variáveis ​​de membro da classe.

2)  Em seguida, a classe base é inicializada.

3)  Em seguida, todas as variáveis ​​recebem valores, se algum for especificado.

4)  Finalmente, o construtor é chamado.

"Não parece muito difícil: primeiro as variáveis, depois o construtor."

"Vamos ver como isso funciona em um exemplo com duas classes:"

Código Descrição
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; ←-
 }
}
Declare duas classes: Pet(pet) e Cat(cat).

Na classe Cat, vemos uma chamada explícita ao construtor da classe base .
Deve estar sempre na primeira linha do construtor.

Veja o que acontece depois que a memória é alocada:
18  – chame o construtor da classe base.
3, 4  – inicializar variáveis ​​em Pet.
8, 9  – execute o código no construtor Pet.

Então a classe Cat começa a ser inicializada.
14  – inicializa variáveis ​​em Cat
19  – executa o código no construtor Cat

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

"Isso é um pouco confuso. Por que é tão complicado?"

"Na verdade, não é difícil se você souber o que realmente está acontecendo:"

Se uma classe não tiver nenhum construtor, um será criado automaticamente.

Construtor padrão
class Cat
{
 int x = 5;
 int y = 5;
}
class Cat
{
 int x = 5;
 int y = 5;
 public Cat() 
 {
 }
}

Se você não chamar o construtor da classe base, ele será chamado automaticamente.

Chamada do construtor da classe base
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();
 }
}

As variáveis ​​de membro são inicializadas no construtor.

Inicialização de variáveis ​​de membro
class Cat
{
 int x = 5;
 int y = 5;
}
class Cat
{
 int x;
 int y;
 public Cat()
 {
  super();
  this.x = 5;
  this.y = 5;
  }
}
O que realmente acontece
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)
 {
  //call of the base class's constructor
  super();
  //initialize variables
  this.x = 5;
  this.y = 5;
  this.weight = 10;
  //execute the constructor code
  this.x = x;
  this.y = y;
 }
}
class Cat extends Pet
{
 int tailLength;
 int age;
 Cat(int x, int y, int age)
 {
  //call of the base class's constructor
   super(x, y);
  //initialize variables
  this.tailLength = 8;
  //execute the constructor code
  this.age = age;
 }
}

"Agora está muito mais claro: primeiro a classe base, depois as variáveis ​​fora do construtor, depois o código do construtor."

"Muito bem, Amigo! É isso!"