Po prostu próbowałem ustawić zmienną, pokazując mi, że super konstruktor został zakończony bez marnowania mojego kodu. Więc przypomniałem sobie, jak zainicjowano zmienne klasy; po super konstruktorze, ale przed konstruktorem klasy. Ale jest coś dziwnego, jeśli spojrzeć na ten przykład:Różnica między inicjalizacją ostatniej klasy zmiennej
public class Init {
public Init() {
System.out.println("Init instance of " + this.getClass().getSimpleName());
System.out.println("syso Init:");
this.syso(false);
}
protected void syso(boolean childCall) {
System.out.println("should not be printed because the method is overwitten");
}
public static class Child extends Init {
private final boolean finalTrueA = true;
private final boolean finalTrueB;
private final boolean finalTrueC;
private boolean nonFinalTrueA = true;
private boolean nonFinalTrueB;
private boolean nonFinalTrueC;
{
this.finalTrueB = true;
this.nonFinalTrueB = true;
}
public Child() {
super();
this.finalTrueC = true;
this.nonFinalTrueC = true;
System.out.println("\n\nsyso Child:");
this.syso(true);
}
@Override
protected void syso(boolean childCall) {
System.out.println("finalTrueA " + this.finalTrueA + " should be " + childCall);
System.out.println("finalTrueB " + this.finalTrueB + " should be " + childCall);
System.out.println("finalTrueC " + this.finalTrueC + " should be " + childCall);
System.out.println();
System.out.println("nonFinalTrueA " + this.nonFinalTrueA + " should be " + childCall);
System.out.println("nonFinalTrueB " + this.nonFinalTrueB + " should be " + childCall);
System.out.println("nonFinalTrueC " + this.nonFinalTrueC + " should be " + childCall);
}
}
public static void main(String[] args) {
@SuppressWarnings("unused")
Child child = new Child();
}
}
który ma następujący wynik:
Init instance of Child
syso Init:
finalTrueA true should be false // <-- why??????????
finalTrueB false should be false
finalTrueC false should be false
nonFinalTrueA false should be false
nonFinalTrueB false should be false
nonFinalTrueC false should be false
syso Child:
finalTrueA true should be true
finalTrueB true should be true
finalTrueC true should be true
nonFinalTrueA true should be true
nonFinalTrueB true should be true
nonFinalTrueC true should be true
Ten efekt można zaobserwować na wyjściu Zaćmienie jak również na prowadzenie klasę javac. Ale debugger eclipse pokazuje poprawną wartość finalTrueA w obrębie super konstruktora wywołania metody syso.
Moje pytanie: czy ten efekt jest prawidłowy, że różne inicjowanie powoduje różne zachowanie pól statycznych i jest to błąd debuggera Eclipse, czy to zachowanie jest nieprawidłowe i jest to błąd java ???
Interesujące. Wygląda na to, że ma to wpływ tylko na pola "final", które mają inicjator używający wartości stałej w czasie kompilacji. –
To zachowanie jest poprawne, ale nie każdy programista jest tego świadomy. – Holger