Po pierwsze, układanka: co drukuje następujący kod?
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;
}
}
Odpowiedź:
0
Spojlery poniżej.
Jeśli drukujesz Xw skali (długiej) i redefiniujesz X = scale(10) + 3, wydruki będą X = 0wtedy X = 3. Oznacza to, że Xjest tymczasowo ustawiony na, 0a później ustawiony na 3. To jest naruszenie final!
Modyfikator statyczny w połączeniu z modyfikatorem końcowym służy również do definiowania stałych. Ostatni modyfikator wskazuje, że wartość tego pola nie może się zmienić .
Źródło: https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html [podkreślenie dodane]
Moje pytanie: czy to błąd? Jest finalźle zdefiniowany?
Oto kod, który mnie interesuje.
XPrzypisano mu dwie różne wartości: 0i 3. Uważam, że jest to naruszenie 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;
}
}
To pytanie zostało oznaczone jako możliwy duplikat statycznej kolejności inicjalizacji pola końcowego Java . Uważam, że to pytanie nie jest duplikatem, ponieważ drugie pytanie dotyczy kolejności inicjalizacji, podczas gdy moje pytanie dotyczy cyklicznej inicjalizacji połączonej ze finalznacznikiem. Na podstawie samego drugiego pytania nie byłbym w stanie zrozumieć, dlaczego kod w moim pytaniu nie powoduje błędu.
Jest to szczególnie wyraźne, patrząc na wyniki, które otrzymuje Ernest: gdy ajest oznaczony final, otrzymuje następujące dane wyjściowe:
a=5
a=5
co nie obejmuje głównej części mojego pytania: w jaki sposób finalzmienna zmienia swoją zmienną?
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.
Xczłonka jest jak odwoływanie się do członka podklasy przed zakończeniem konstruktora superklasy, to twój problem, a nie definicjafinal.