Em que ordem os blocos estáticos e variables ​​estáticas em uma class são executados?

Duplicar Possível:
Inicialização de class estática de Java

Por que a variável de string é atualizada no bloco de boot e não no inteiro (mesmo que o bloco seja escrito primeiro)

class NewClass { static { System.out.println(NewClass.string+" "+NewClass.integer); } final static String string="static"; final static Integer integer=1; public static void main(String [] args)//throws Exception { } } 

Minha saída é

 static null 

PS: Também notei que a boot da variável string acontece antes do bloco somente quando eu insiro o modificador final. Por que não por inteiro também? Eu o declarei como estática final também

Da seção 12.4.2 do JLS, cortou apropriadamente:

O procedimento para inicializar C é o seguinte:

  • Em seguida, inicialize as variables ​​de class final e os campos das interfaces cujos valores são expressões constantes de tempo de compilation (§8.3.2.1, §9.3.1, §13.4.9, §15.28).

  • Em seguida, execute os inicializadores de variável de class e os inicializadores estáticos da class, ou os inicializadores de campo da interface, em ordem textual, como se fossem um único bloco.

Portanto, para constantes de tempo não compiladas, não é um caso de “todas as variables” e “todos os inicializadores estáticos” ou vice-versa – são todos eles juntos, em ordem textual. Então, se você tivesse:

 static int x = method("x"); static { System.out.println("init 1"); } static int y = method("y"); static { System.out.println("init 2"); } static int method(String name) { System.out.println(name); return 0; } 

Então a saída seria:

 x init 1 y init 2 

Mesmo fazer x ou y final não afetaria isso aqui, pois eles ainda não seriam constantes de tempo de compilation.

PS: Também notei que a boot da variável string acontece antes do bloco somente quando eu insiro o modificador final.

Nesse ponto, é uma constante de tempo de compilation e qualquer uso dela é basicamente embutido. Além disso, o valor da variável é atribuído antes do restante dos inicializadores, como acima.

A Seção 15.28 do JLS define constantes de tempo de compilation – ele inclui todos os valores primitivos e String , mas não os tipos de invólucro, como Integer .

Aqui está uma resposta curta e direta para você pergunta ….

static Variable :

Variáveis ​​estáticas são executadas quando a JVM carrega a Class e a Class é carregada quando ela é instanciada ou seu static method está sendo chamado.

static Block or static Initializer Block :

O Initializer Block estático estático fica inicializado antes da Class ser instanciada ou antes de seu static method ser chamado, e Even antes de sua static variable ser usada.

///////// Editado Part /////////

 class NewClass { final static String string = "static"; final static Integer integer = 1; static { System.out.println(NewClas.string + " " + NewClas.integer); } public static void main(String [] args) { // throws Exception new NewClas(); } } 

O acima irá imprimir static 1 .

O motivo é que a JVM fará o processo de otimização conhecido como Constant folding , fazendo um pré-cálculo das variables ​​constantes.

Além disso, no seu caso, o resultado foi static null causa Constant folding é aplicado ao tipo primitivo e não Wrapper Object, no seu caso, o seu Integer …

Eles são inicializados na ordem dada (campos e blocos estáticos), é por isso que o valor impresso é null , nada foi atribuído a campos estáticos definidos após o bloco estático.