Exercicio de Concurso

Olá,

Gostaria de uma explicaçao detalhada sobre este exercicio:

[code]
class SuperInicializacao {
SuperInializacao() {
System.out.print(“A”) ;
}

{
    System.out.print("B") ;
} 

 static  {
    System.out.print("C") ;
 }

}
public class Inializacao extends SuperInializacao {
Inicializacao() {
System.out.print(“D”) ;
}

  {
       System.out.print("E") ;
  }

  static  {
        System.out.print("F") ;
  }

  public static void main(String[ ] args)    {
       Inicializacao in = new Inicializacao() ;
  }

}[/code]

Porque a saida dele é: CFBAED?
O pouco que sei é que a classe Inicializacao herda da class SuperInicializacao e métodos e atributos estáticos só podem acessar outros métodos e atributos estáticos da mesma classe e que o metodo static só poder ser chamado atraves da classe.
Se o objeto instaciado in é da classe Inicializacao porque foi executado metodo static da classe SuperInicializacao: ?

static  {
        System.out.print("C") ;
         }  

Obrigado.

Blocos de inicialização estáticos são chamados primeiro, assim que as classes são carregadas, logo após vêm os blocos de inicialização, depois o construtor das superclasses (classes pais) depois o construtor da classe!

 class SuperInicializacao    {  
     SuperInicializacao()   {  
         System.out.print("A") ;  
     }  
   
     {  
         System.out.print("B") ;  
     }   
   
      static  {  
         System.out.print("C") ;  
      }  
 }  
 public class Inicializacao extends SuperInicializacao  {  
       Inicializacao()   {  
            System.out.print("D") ;  
       }  
         
       {  
            System.out.print("E") ;  
       }  
   
       static  {  
             System.out.print("F") ;  
       }  
   
       public static void main(String[ ] args)    {  
            Inicializacao in = new Inicializacao() ;  
       }  
 } 

a) Você chama o método main da classe Inicialização, que deve ser carregada
b) A classe Inicialização requer o carregamento da classe SuperInicialização
c) O carregamento da classe SuperInicialização força a execução do static block, fazendo que se imprima “C”
d) Como as classes de que depende a Inicialização foram carregadas, agora é a vez de acabar de carregar a classe Inicialização
e) O carregamento da classe Inicialização força a execução do static block, fazendo que se imprima “F”
f) Agora podemos chamar o construtor default da classe Inicialização.
g) O construtor default da classe Inicialização chama implicitamente o construtor default da classe SuperInicialização
h) O construtor default da classe SuperInicialização deve chamar o bloco anônimo ("{ System.out.println (“B”); }") antes de
executar o código escrito no próprio construtor. Isso imprime “B”
i) Agora sim o construtor default da classe SuperInicialização pode imprimir “A”.
j) Voltando ao processamento do construtor default da classe Inicialização, agora devemos chamar o bloco anônimo
("{ System.out.println (“E”); }") . Isso imprime “E”
k) Por fim, devemos executar o código escrito no próprio construtor default da classe Inicialização, que imprime “D”.

Entao a classe Inicialização executou 1º o bloco estatico da classe SuperInicialização porque a classe Inicializacao herda da classe SuperInicializacao?
Se nao tivesse a herança da classe SuperInicializacao ele iria executar o bloco estatico da classe Inicializacao?É isso?

Entao existe um ordem de execucaçao dos metodos:

  1. metodos estaticos
    2)bloco anonimo
    3)código escrito no próprio construtor default da classe Inicialização.

Sim para as duas perguntas, mas reformulando a ordem de execução seria:

1º Blocos estáticos (começando a partir da super classe, se houver)
2º Blocos de inicialização (começando a partir da super classe, se houver)
3° Construtor (começando a partir da super classe, se houver, aqui entra o construtor que foi chamado, caso não seja chamado explicitamente um outro contrutor que não seja o default, caso contrário, será o construtor default que será executado)

Os blocos estaticos são carregados assim que voce carrega uma classe.

Exemplo

package br;
public class A{
static{
System.out.println("classe A carregada");
}
public static void doNothing(){}
}

public class B{
public static void main(String...args){
Class.forName("br.A");//Isso causa o carregamento da classe
A.doNothing();//Aqui também carregaria a classe caso não tivesse sido carregada com Class.forName
}
}

Duvida sanada!

Obrigado thiago.correa, thingol e Mark_Ameba.

  • uma liçao aprendida!

Ate mais rapaziada.