Java-Konstruktor und Feld-Initialisierung Um
Ich mir bewusst, dass Java-Objekt-Konstruktoren implizit initialisieren Ihrer Instanz nicht-statische Felder. Allerdings bin ich mir nicht sicher über die Reihenfolge, dass dies geschieht in einer Klassen-Hierarchie. Zum Beispiel:
abstract public class AbstractPieceSequence implements PieceSequence
{
private Tetromino current;
private Tetromino preview;
public AbstractPieceSequence()
{
advance();
}
@Override
public final void advance()
{
if (preview == null) {
current = getNextPiece();
preview = getNextPiece();
} else {
current = preview;
preview = getNextPiece();
}
}
abstract protected Tetromino getNextPiece();
}
public class ShufflePieceSequence extends AbstractPieceSequence
{
private List<Shape> bag = new LinkedList<Shape>();
@Override
protected Tetromino getNextPiece()
{
if (bag.size() == 0) {
Collections.addAll(bag, Shape.I, Shape.J, Shape.L, Shape.O, Shape.S, Shape.T, Shape.Z);
}
return Tetromino.tetrominoes.get(bag.remove(0));
}
}
Den übergeordneten Konstruktor ruft eine Methode in der child-Klasse, die eine exception wirft, als der Wert List<Shape> bag
ist derzeit null.
Kann ich definieren, ein Kind-Konstruktor aufrufen super(), aber das muss die erste Zeile in den Konstruktor Körper (was bedeutet, dass ich nicht noch eine chance zu initialisieren Tasche vor getNextPiece
genannt wird).
Bin ich etwas fehlt offensichtlich.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Richtig.
super()
, auch wenn Sie nicht hinzufügen es sich ausdrücklich vor, platziert implictly in jedem Konstruktor. Dies bedeutet, dass der Konstruktor vonShufflePieceSequence
zum ersten mal aufgerufen wird, sondern das, was er tut, ist die BerufungAbstractPieceSequence
.In
AbstractPieceSequence
Sie anrufen, eine Methode definiert, die inShufflePieceSequence
-, die nicht initialisiert wurde. In der Tat, was Sie tun, ist eigentlich ein sehr subtilen Fehler. Sie sollten nie nennen überschreibbare (einschließlichabstract
Methoden) aus dem Konstruktor. Zeitraum. ANMUTIGEN tools wie pmd und findbugs, markieren Sie diese als einen möglichen Fehler.Siehe auch
Objekt-Felder werden nicht implizit initialisiert... dazu musst du die init. Vielleicht brauchen Sie ein lazy init in diesem Fall? In der Regel unangenehm für den Konstruktor aufrufen von Methoden, die nicht-triviale arbeiten, ist es normalerweise eine Geruch, der etwas komplexer ist, als es sein will.
Depth-first, pre-order gehen.
Anders ist ein guter Punkt: Java nur initialisiert Felder, die nativen Typen implizit. Jedes Objekt-Feld ist lediglich eine Referenz auf Objekt, und so ist es in der Tat initialisiert, aber es initialisiert
null
.Der Reihenfolge für den Aufruf der Konstruktoren der Übergeordneten Sub-class im Falle der Vererbung ist, dass der Konstruktor der Übergeordneten Klasse bekommt immer aufrufen und erst dann der Konstruktor der abgeleiteten Klasse.
Den Sub-Klasse ruft den Konstruktor der Basis-Klasse standardmäßig mit dem Super(), wenn explizit nicht gegeben.