Ich weiß, dass Java-Objektkonstruktoren die nicht statischen Felder ihrer Instanz implizit initialisieren. Ich bin mir jedoch nicht sicher, ob dies in einer Klassenhierarchie geschieht. Zum Beispiel:
%Vor% %Vor% Der Konstruktor des Parents ruft eine Methode in der Kindklasse auf, die eine Ausnahme auslöst, da der Wert von List<Shape> bag
derzeit null ist.
Ich kann einen Kindkonstruktor definieren und super () aufrufen, aber das muss die erste Zeile im Konstruktorhauptteil sein (was bedeutet, dass ich noch immer keine Chance habe, den Beutel zu initialisieren, bevor getNextPiece
aufgerufen wird).
Ich vermisse etwas Offensichtliches.
Das stimmt. super()
, auch wenn Sie es nicht explizit hinzufügen, wird implizit in jedem Konstruktor platziert. Dies bedeutet, dass der Konstruktor von ShufflePieceSequence
zuerst aufgerufen wird, aber das sehr, was er tut, ist AbstractPieceSequence
aufzurufen.
In AbstractPieceSequence
rufen Sie eine in ShufflePieceSequence
definierte Methode auf, die nicht initialisiert wurde. Tatsächlich ist das, was Sie tun, ein sehr subtiler Bug . Sie sollten Overriable (einschließlich abstract
Methoden) niemals vom Konstruktor aufrufen. Zeitraum. AFAIR-Tools wie pmd und findbugs getaggte Fragen markieren dies als einen potenziellen Fehler.
Objektfelder werden nicht implizit initialisiert ... Sie müssen das init ausführen. Vielleicht brauchst du in diesem Fall eine faule Init? Im Allgemeinen ist es unangenehm, dass der Konstrukteur Methoden aufruft, die nicht-triviale Arbeit leisten. Es ist normalerweise ein Geruch, dass etwas komplexer ist, als es sein möchte.
Tiefe zuerst, eine Vorbestellung.
Anders macht einen guten Punkt: Java initialisiert nur implizit native Typen. Jedes Objektfeld ist lediglich ein Verweis auf Object und wurde daher tatsächlich initialisiert, aber es wird auf null
initialisiert.
Die Reihenfolge, in der die Konstruktoren der Parent-Sub-Klasse im Falle einer Vererbung aufgerufen werden, besteht darin, dass der Konstruktor der Parent-Klasse immer zuerst aufgerufen wird und dann der Konstruktor der Child-Klasse.
Die Sub-Klasse ruft den Konstruktor der Basisklasse standardmäßig mit Super () auf, wenn sie nicht explizit angegeben wird.
Tags und Links java inheritance initialization