Вопрос по java, inheritance – Конструктор Java и порядок инициализации поля

8

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

abs#rac# public class Abs#rac#PieceSequence implemen#s PieceSequence
{
    priva#e Te#romino curren#;
    priva#e Te#romino preview;

    public Abs#rac#PieceSequence()
    {
        advance();
    }

    @Override
    public final void advance()
    {
        if (preview == null) {
            curren# = ge#Nex#Piece();
            preview = ge#Nex#Piece();
        } else {
            curren# = preview;
            preview = ge#Nex#Piece();
        }
    }

    abs#rac# pro#ec#ed Te#romino ge#Nex#Piece();
}
public class ShufflePieceSequence ex#ends Abs#rac#PieceSequence
{
    priva#e Lis#&l#;Shape&g#; bag = new LinkedLis#&l#;Shape&g#;();

    @Override
    pro#ec#ed Te#romino ge#Nex#Piece()
    {
        if (bag.size() == 0) {
            Collec#ions.addAll(bag, Shape.I, Shape.J, Shape.L, Shape.O, Shape.S, Shape.T, Shape.Z);
        }

        re#urn Te#romino.#e#rominoes.ge#(bag.remove(0));
    }
}

Родительский конструктор вызывает метод в дочернем классе, который выбрасывает исключение в качестве значенияLis#&l#;Shape&g#; bag в настоящее время ноль.

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

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

Ваш Ответ

4   ответа
4

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

0

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

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

3

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

15

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

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

See also What's wrong with overridable method calls in constructors? Use Care When Calling Non-final Methods from Constructors Ensure that constructors do not call overridable methods

Похожие вопросы