Estou me perguntando quando as variáveis estáticas são inicializadas com seus valores padrão. É correto que, quando uma classe é carregada, vars estáticos são criados (alocados) e, em seguida, inicializadores estáticos e inicializações em declarações são executados? Em que ponto os valores padrão são fornecidos? Isso leva ao problema da referência direta.
Além disso, se você puder explicar isso em referência à pergunta feita em Por que campos estáticos não são inicializados a tempo? e principalmente a resposta dada por Kevin Brock no mesmo site. Não consigo entender o terceiro ponto.
java
static
initialization
Ankit
fonte
fonte
Respostas:
Em Consulte Métodos de variável estática Java :
Variáveis de instância e classe (estáticas) são inicializadas automaticamente com os valores padrão padrão se você falhar em inicializá-las propositalmente. Embora as variáveis locais não sejam inicializadas automaticamente, você não pode compilar um programa que falha ao inicializar uma variável local ou atribuir um valor a essa variável local antes de ser usada.
O que o compilador realmente faz é produzir internamente uma única rotina de inicialização de classe que combina todos os inicializadores de variáveis estáticas e todos os blocos inicializadores estáticos de código, na ordem em que aparecem na declaração de classe. Este único procedimento de inicialização é executado automaticamente, apenas uma vez, quando a classe é carregada pela primeira vez.
No caso de classes internas , eles não podem ter campos estáticos
Consulte JLS 8.1.3 Classes internas e instâncias anexas
final
campos em Java podem ser inicializados separadamente de seu local de declaração; entretanto, não pode ser aplicável astatic final
campos. Veja o exemplo abaixo.final class Demo { private final int x; private static final int z; //must be initialized here. static { z = 10; //It can be initialized here. } public Demo(int x) { this.x=x; //This is possible. //z=15; compiler-error - can not assign a value to a final variable z } }
Isso ocorre porque há apenas uma cópia das
static
variáveis associadas ao tipo, ao invés de uma associada a cada instância do tipo como com as variáveis de instância e se tentarmos inicializar oz
tipostatic final
dentro do construtor, ele tentará reinicializar ostatic final
campo de tipoz
porque o construtor é executado em cada instanciação da classe que não deve ocorrer emfinal
campos estáticos .fonte
In case of static inner classes, they can not have static fields
parece um erro de digitação. As classes internas não são estáticas.Vejo:
O último, em particular, fornece etapas de inicialização detalhadas que explicam quando as variáveis estáticas são inicializadas e em que ordem (com a ressalva de que
final
as variáveis de classe e os campos de interface que são constantes de tempo de compilação são inicializados primeiro).Não tenho certeza de qual é a sua pergunta específica sobre o ponto 3 (supondo que você se refira ao aninhado?). A sequência detalhada afirma que esta seria uma solicitação de inicialização recursiva, portanto, ela continuará a inicialização.
fonte
Os campos estáticos são inicializados quando a classe é carregada pelo carregador de classes. Os valores padrão são atribuídos neste momento. Isso é feito na ordem em que aparecem no código-fonte.
fonte
A ordem de inicialização é:
Os detalhes do processo são explicados no documento de especificação da JVM .
fonte
variável estática
fonte
Começando com o código da outra pergunta:
class MyClass { private static MyClass myClass = new MyClass(); private static final Object obj = new Object(); public MyClass() { System.out.println(obj); // will print null once } }
Uma referência a esta classe iniciará a inicialização. Primeiro, a classe será marcada como inicializada. Em seguida, o primeiro campo estático será inicializado com uma nova instância de MyClass (). Observe que myClass recebe imediatamente uma referência a uma instância MyClass em branco . O espaço está lá, mas todos os valores são nulos. O construtor agora é executado e imprime
obj
, que é nulo.Agora, de volta à inicialização da classe:
obj
é feita uma referência a um novo objeto real e pronto.Se isso foi acionado por uma instrução como:
MyClass mc = new MyClass();
espaço para uma nova instância MyClass é novamente alocado (e a referência colocadamc
). O construtor é executado novamente e imprime novamenteobj
, que agora não é nulo.O verdadeiro truque aqui é que, quando você usa
new
, as inWhatEverItIs weii = new WhatEverItIs( p1, p2 );
weii
é imediatamente fornecida uma referência a um pouco de memória nula. A JVM irá então inicializar os valores e executar o construtor. Mas se você de alguma forma referenciarweii
antes disso - referenciando-o a partir de outro thread ou ou referenciando a partir da inicialização da classe, por exemplo - você está olhando para uma instância de classe preenchida com valores nulos.fonte
A variável estática pode ser inicializada das seguintes três maneiras como a seguir escolha qualquer uma de sua preferência
ou você pode fazer criando um bloco estático, por exemplo:
static { // whatever code is needed for initialization goes here }
Existe uma alternativa aos blocos estáticos - você pode escrever um método estático privado
class name { public static varType myVar = initializeVar(); private static varType initializeVar() { // initialization code goes here } }
fonte