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 X
em escala (longa) e redefinir X = scale(10) + 3
, as impressões serão X = 0
então X = 3
. Isso significa que X
está temporariamente definido como 0
e 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á final
mal definido?
Aqui está o código no qual estou interessado.
X
Recebe dois valores diferentes: 0
e 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 final
tag. 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 final
variá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.
X
membro é 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
.