diese beiden Klassen vor:Initialisierungsreihenfolge der endgültigen Felder
public abstract class Bar {
protected Bar() {
System.out.println(getValue());
}
protected abstract int getValue();
}
public class Foo extends Bar {
private final int i = 20;
public Foo() {
}
@Override
protected int getValue() {
return i;
}
public static void main(String[] args) {
new Foo();
}
}
Wenn ich Foo ausführen, wird der Ausgang 20
ist Wenn ich das Feld nicht endgültig zu machen, oder wenn ich initialisieren es in der Foo Konstruktor, der Ausgang ist 0.
Meine Frage ist: Was ist die Reihenfolge der Initialisierung im Falle der endgültigen Felder und wo ist dieses Verhalten in der JLS beschrieben?
Ich erwartete, einige Ausnahme Regel über endgültige Felder here zu finden, aber wenn ich etwas nicht vermisse, gibt es nicht.
Beachten Sie, dass ich weiß, ich sollte nie eine überschreibbare Methode von einem Konstruktor aufrufen. Das ist nicht der Punkt der Frage.
Hatte meinen Kommentar über 'final int' zu entfernen, da es eine * Kompilierzeitkonstante * war (hatte keine * unterstützenden Beweise * ..War auf der Suche nach dieser Antwort .. Danke). +1: P .. – TheLostMind
Guter Punkt. Ich habe diese Referenz "konstante Variable" vermisst (was für ein Oxymoron!). Aber ich verstehe immer noch nicht, was sich bei der Objektinitialisierung ändert. Wann ist diese konstante Variable zugewiesen? Die detaillierte Initialisierungsprozedur spricht über die Klasseninitialisierung und spricht über die Initialisierung von "finalen Klassenvariablen", aber nicht über die Initialisierung von "letzten Instanzvariablen" (es sei denn, ich vermisse etwas wieder). –
OK. Ich habe es gefunden. http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.2 sagt: "Einige Ausdrücke haben einen Wert, der zur Kompilierzeit bestimmt werden kann. Dies sind konstante Ausdrücke (§15.28). ". Und http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28 sagt, dass "Einfache Namen (§6.5.6.1), die sich auf konstante Variablen beziehen (§4.12. 4) "sind konstante Ausdrücke. Also ist 'i' in' getValue() 'ein einfacher Name, der sich auf eine konstante Variable bezieht und dessen Wert somit zur Kompilierzeit bekannt ist. –