java 构造函数初始化顺序,Java构造函数和字段初始化顺序

I aware that Java object constructors implicitly initialize their instance's non-static fields. However, I'm unsure of the order that this happens in a class hierarchy. For example:

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 bag = new LinkedList();

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

}

}

The parent's constructor calls a method in the child class, which throws an exception as the value of List bag is currently null.

I can define a child constructor and call super(), but that must be the first line in the constructor body (which means I still don't have a chance to initialize bag before getNextPiece is called).

I am missing something obvious.

解决方案

That's right. super(), even if you don't add it explicitly, is placed implictly in every constructor. This means that the constructor of ShufflePieceSequence is called first, but the very very thing it does is calling AbstractPieceSequence.

In AbstractPieceSequence you are calling a method defined in ShufflePieceSequence - which has not been initialized. In fact what you are doing is actually a very subtle bug. You should never call overridable (including abstract methods) from constructor. Period. AFAIR tools like pmd and findbugs are marking this as a potential bug.

See also

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值