Primeiro, um quebra-cabeça: o que o código a seguir imprime?
public class RecursiveStatic {
public static void main(String[] args) {
System.out.println(scale(5));
}
private static final long X = scale(10);
private static long scale(long value) {
return X * value;
}
}
Responda:
0 0
Spoilers abaixo.
Se você imprimir Xem escala (longa) e redefinir X = scale(10) + 3, as impressões serão X = 0então X = 3. Isso significa que Xestá temporariamente definido como 0e posteriormente definido como 3. Isso é uma violação de final!
O modificador estático, em combinação com o modificador final, também é usado para definir constantes. O modificador final indica que o valor desse campo não pode ser alterado .
Fonte: https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html [ênfase adicionada]
Minha pergunta: isso é um bug? Está finalmal definido?
Aqui está o código no qual estou interessado.
XRecebe dois valores diferentes: 0e 3. Eu acredito que isso seja uma violação de final.
public class RecursiveStatic {
public static void main(String[] args) {
System.out.println(scale(5));
}
private static final long X = scale(10) + 3;
private static long scale(long value) {
System.out.println("X = " + X);
return X * value;
}
}
Esta pergunta foi sinalizada como uma possível duplicata da ordem de inicialização do campo final estático de Java . Acredito que esta questão não seja uma duplicata, pois a outra pergunta aborda a ordem de inicialização, enquanto minha pergunta aborda uma inicialização cíclica combinada com a finaltag. Apenas a partir da outra pergunta, não seria possível entender por que o código na minha pergunta não comete um erro.
Isso é especialmente claro ao observar a saída que o ernesto obtém: quando aé marcado com final, ele obtém a seguinte saída:
a=5
a=5
que não envolve a parte principal da minha pergunta: como uma finalvariável altera sua variável?
A blank final instance variable must be definitely assigned (§16.9) at the end of every constructor (§8.8) of the class in which it is declared; otherwise a compile-time error occurs.
Xmembro é como se referir a um membro da subclasse antes que o construtor da superclasse termine, esse é seu problema e não a definição definal.