final非null字段变为null

时间:2016-06-15 21:43:31

标签: java jls

这怎么可能?

public class WritableByteChannelEndpoint extends Endpoint<ByteBuffer> {

    private final WritableByteChannel channel;

    public WritableByteChannelEndpoint(WritableByteChannel channel, Observable<ByteBuffer> observable) {
        super(observable);
        this.channel = Objects.requireNonNull(channel);
    }

    // ...

    @Override
    public void onNext(ByteBuffer input) {
        assert channel != null;
        // ...
    }

}

我在该行中收到断言错误。出于某种原因,我无法理解,channel为空。

当我使用JUnit执行单元测试时,偶尔会发生这种情况。

理论上是否可能,整个WritableByteChannelEndpoint实例已经被垃圾收集,channel被设置为null,但是其他一些对象仍然有(弱?参考它?

1 个答案:

答案 0 :(得分:3)

在通过弱引用怀疑奇怪的GC行为之前,请考虑更可能的竞争条件:构造函数在设置this.channel之前调用超类构造函数。因此,超类构造函数可以将WritableByteChannelEndpoint泄漏到正在构造的this,导致在子类构造函数有机会设置{{1}的值之前调用onNext }。您的最后一个字段 为空,因为它没有机会在时间上非空(间歇性地)。