Java конструктор и порядок инициализации поля

Я знаю, что конструкторы объектов Java неявно инициализируют нестатические поля своего экземпляра. Однако я не уверен в том, что это происходит в иерархии классов. Например

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));
    }
}

Конструктор родителя вызывает метод в дочернем классе, который выбрасывает исключение как значениеList<Shape> bag в настоящее время ноль.

Я могу определить дочерний конструктор и вызвать super (), но это должна быть первая строка в теле конструктора (что означает, что у меня все еще нет возможности инициализировать bag передgetNextPiece называется)

Я упускаю что-то очевидное.

Ответы на вопрос(4)

Решение Вопроса

super(), даже если вы не добавите его явно, помещается неявно в каждый конструктор. Это означает, что конструкторShufflePieceSequenceначала вызывается @, но самое оно вызываетAbstractPieceSequence.

ВAbstractPieceSequence вы вызываете метод, определенный вShufflePieceSequence - который не был инициализирован. На самом деле то, что вы делаете, это на самом деле очень тонкий баг. Вы никогда не должны называть переопределенными (включаяabstract методы) из конструктора. Период. AFAIR инструменты, такие как PMD а также FindBugs помечают это как потенциальную ошибку.

Смотрите такж Что не так с переопределенными вызовами методов в конструкторах? Используйте осторожность при вызове не финальных методов от конструкторов Убедитесь, что конструкторы не вызывают переопределенные методы

изацию. Может быть, вам нужен ленивый инициатор в этом случае? Обычно неприятно иметь конструктор, вызывающий методы, которые выполняют нетривиальную работу, обычно пахнет чем-то более сложным, чем он хочет быть.

аков, что сначала всегда вызывается конструктор класса Parent, а затем конструктор класса Child.

Sub-класс вызывает конструктор базового класса по умолчанию, используя Super (), если явно не указано.

Anders делает хорошее замечание: Java инициализирует только поля, которые являются неявными типами. Любое поле Object является просто ссылкой на Object, поэтому оно фактически инициализировано, но инициализировано какnull.

Ваш ответ на вопрос