Passo a passo para construção de um objeto em Runtime:
1 - Memória é alocada para o objeto
2 - Variaveis de Instancia recebem valor Default
3 - Verifica-se se Parametros e argumentos tem mesmo tipo,ordem,quantidade
4 - Tem this explicito? Se tiver executa this, isso se this for chamada a outro construtor
5 - Chamar super(), implicito ou explicito(De qualquer modo ele sempre é chamado)
6 - Executa-se os inicializados das variáveis de instancia(Explicitos)
7 - Executa - se o bloco_de_codigo do construtor
Considerações:
- O passo 1 e passo 2 somente são feitos uma vez
- O passo 4 só é considerado se tiver uma CHAMADA this sozinha a outro construtor.
- O passo 5 sempre é feito, independente se explicitamente ou implicitamente, só não é feito em java.lang.Object porque ele ja é TOPO da hierarquia.
- O passo 6 é considerado SOMENTE quando você inicializa a variavel quando declara
Exemplo:
public int variable = 20;
Se a inicialização for feita dentro do construtor é considerado passo 7:
public int variable;
public Classe(){
variable = 20;
}
Oque acontece se houver uma chamada a this?
Se houver uma chamada explicita a this para outro construtor, entra outro construtor e incia-se do numero 3 em diante.
Oque é aload_0?
aload_0 é o this, ou seja uma referência a Constant Pool, que depois será Runtime Constant Pool e consequentemente com dynamic Linking a Heap
Posso ter this e super no mesmo construtor?
Sabemos que this ou super devem esta na primeira linha do construtor, logo se temos this não temos super e se temos super não temos this, Pois ambos tem que estar na primeira linha do construtor.
Vejamos um exemplo:
public class Pessoa{
private String name;
private String endereco;
private int numeroCasa;
public Pessoa(String name,String endereco,int numeroCasa){
this.name= name;
this.endereco = endereco;
this.numeroCasa = numeroCasa;
}
public Pessoa(String name,String endereco){
this(name,endereco,0);
}
public static void main(String array[ ]){
Pessoa maria = new Pessoa("Maria","Rua das flores");
}
}
Em Sintaxe bytecode temos:
Compiled from "Pessoa.java"
public class Pessoa extends java.lang.Object{
public Pessoa(java.lang.String, java.lang.String, int);
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."
4: aload_0
5: aload_1
6: putfield #2; //Field name:Ljava/lang/String;
9: aload_0
10: aload_2
11: putfield #3; //Field endereco:Ljava/lang/String;
14: aload_0
15: iload_3
16: putfield #4; //Field numeroCasa:I
19: return
public Pessoa(java.lang.String, java.lang.String);
Code:
0: aload_0
1: aload_1
2: aload_2
3: iconst_0
4: invokespecial #5; //Method "
7: return
public static void main(java.lang.String[]);
Code:
0: new #6; //class Pessoa
3: dup
4: ldc #7; //String Maria
6: ldc #8; //String Rua das flores
8: invokespecial #9; //Method "
11: astore_1
12: return
}
No frame main, podemos verificar alguns passos:
Code:
0: new #6; //class Pessoa
3: dup
4: ldc #7; //String Maria
6: ldc #8; //String Rua das flores
8: invokespecial #9; //Method "init>
11: astore_1
12: return
Passo a passo:
1 - Memória é alocada para o objeto
2 - Variaveis de Instancia recebem valor Default
Podemos considerar instruções iguais em:
0: new #6; //class Pessoa
3: dup
Code:
0: new #6; //class Pessoa
3: dup
4: ldc #7; //String Maria
6: ldc #8; //String Rua das flores
8: invokespecial #9; //Method "init>
Na instrução 8, ele invoca o construtor da propria Classe e passa como parametros oque esta na Operand stack logo estamos no Construtor da classe.
Isso indica que é da própria classe: porque antes de
Vamos para o passo 3 do passo a passo:
3 - Verifica-se se Parametros e argumentos tem mesmo tipo,ordem,quantidade
Logo após feita e confirma o passo 3, estamos dentro do construtor da classe Pessoa
public Pessoa(java.lang.String, java.lang.String);
Code:
0: aload_0
1: aload_1
2: aload_2
3: iconst_0
4: invokespecial #5; //Method "
7: return
Nesse construtor na instrução:
4: invokespecial #5; //Method "init>
Percebemos que estamos no passo 4 do passo a passo
4 - Tem this explicito? Se tiver executa this, isso se this for chamada a outro construtor
Aqui tem this explicito, logo vamos pra o outro construtor da classe:(Perceba que o construtor invocou esse outro construtor, veja que eles tem Argumentos diferentes)
public Pessoa(java.lang.String, java.lang.String, int);
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."
4: aload_0
5: aload_1
6: putfield #2; //Field name:Ljava/lang/String;
9: aload_0
10: aload_2
11: putfield #3; //Field endereco:Ljava/lang/String;
14: aload_0
15: iload_3
16: putfield #4; //Field numeroCasa:I
19: return
Repete-se o processo:
3 - Verifica-se se Parametros e argumentos tem mesmo tipo,ordem,quantidade
4 - Tem this explicito? Se tiver executa this, isso se this for chamada a outro construtor - Nesse caso não tem chamada a this dentro do construtor
5 - Chamar super(), implicito ou explicito(De qualquer modo ele sempre é chamado), Podemos ver isso na instrução:
1: invokespecial #1; //Method java/lang/Object.init>
nessa linha de codigo, nota-se que tem uma invocação na classe:
java/lang/Object
e é o construtor indicado pelo: "
Ou seja invoca-se o construtor da classe java.lang.Object, A superClasse de toda classe em java.Na verdade a instrução
Na classe java.lang.Object temos o teste novamente:
3 - Verifica-se se Parametros e argumentos tem mesmo tipo,ordem,quantidade(Não Tem, pois o construtor não tem argumentos e logo não passamos parametros!!!)
4 - Tem this explicito? Se tiver executa this, isso se this for chamada a outro construtor(Não Tem!!!)
5 - Chamar super(), implicito ou explicito(De qualquer modo ele sempre é chamado)(java.lang.Object é root da hierarquia logo , não temos SuperClass)
6 - Executa-se os inicializados das variáveis de instancia(Explicitos)(Não Tem!!!)
7 - Executa - se o bloco_de_codigo do construtor(Não Tem!!!)
Então voltamos para o construtor da classe Pessoa:
6 - Executa-se os inicializados das variáveis de instancia(Explicitos)
Nesse caso não temos, pois as variaveis de instancia forão declaradas somente e não inicializadas ao declarar
7 - Executa - se o bloco_de_codigo do construtor
this.name= name;
this.endereco = endereco;
this.numeroCasa = numeroCasa;
Terminou-se o bloco de codigo.
Clique na imagem para ampliar
É bom lembrar, que se tivermos "n" classes antes de chegar em java.lang.Object o processo é feito em cada uma das SuperClasses até root,
Vejamos o exemplo:
Clique na imagem para ampliar
Nesse caso se instanciarmos um objeto do tipo Chefe, o passo 1 e 2 só são feitos uma vez e o resto dos passos é feito a cada hierarquia ate java.lang.Object...
Exemplo:
new Chefe();
1 - Memória é alocada para o objeto
2 - Variaveis de Instancia recebem valor Default
3 - Verifica-se se Parametros e argumentos tem mesmo tipo,ordem,quantidade
4 - Tem this explicito? Se tiver executa this, isso se this for chamada a outro construtor - Supondo que não temos this explicito
5 - Chamar super(), implicito ou explicito(De qualquer modo ele sempre é chamado)
Construtor da classe Encarregado pois é super de Chefe:
3 - Verifica-se se Parametros e argumentos tem mesmo tipo,ordem,quantidade
4 - Tem this explicito? Se tiver executa this, isso se this for chamada a outro construtor - Supondo que não temos this explicito
5 - Chamar super(), implicito ou explicito(De qualquer modo ele sempre é chamado)
Construtor da classe Funcionario pois é super de Encarregado:
3 - Verifica-se se Parametros e argumentos tem mesmo tipo,ordem,quantidade
4 - Tem this explicito? Se tiver executa this, isso se this for chamada a outro construtor - Supondo que não temos this explicito
5 - Chamar super(), implicito ou explicito(De qualquer modo ele sempre é chamado)
Construtor da classe java.lang.Object pois é super de Funcionario:
3 - Verifica-se se Parametros e argumentos tem mesmo tipo,ordem,quantidade(Não Tem, Construtor da classe java.lang.Object não requer parametros pois não tem argumentos!!!)
4 - Tem this explicito? Se tiver executa this, isso se this for chamada a outro construtor(Não Tem!!!)
5 - Chamar super(), implicito ou explicito(De qualquer modo ele sempre é chamado)(java.lang.Object é root da hierarquia logo , não temos SuperClass)
6 - Executa-se os inicializados das variáveis de instancia(Explicitos)(Não Tem!!!)
7 - Executa - se o bloco_de_codigo do construtor(Não Tem!!!)
Então agora voltamos para a classe Funcionario:
6 - Executa-se os inicializados das variáveis de instancia(Explicitos)
7 - Executa - se o bloco_de_codigo do construtor
Agora vamos para a classe Encarregado:
6 - Executa-se os inicializados das variáveis de instancia(Explicitos)
7 - Executa - se o bloco_de_codigo do construtor
Agora a classe Chefe:
6 - Executa-se os inicializados das variáveis de instancia(Explicitos)
7 - Executa - se o bloco_de_codigo do construtor
Provando que o passo 5 sempre é executado:
public class Test{
}
Em sintax bytecode temos:
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."
4: return
}
Veja que o construtor da classe é acrescentado pelo compilador, e o mesmo faz uma chamada ao construtor da classe Object:
1: invokespecial #1; //Method java/lang/Object."init>
Bom é isso!!!
Basicamente o construtor vai trabalhando com hierarquia de classes,
CYA DUDES!!!
Muito legal o post
ResponderExcluir