2016-06-15 3 views
3

Как это возможно?окончательный не null поле становится null

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 имеет значение null.

Это происходит каждый раз в то время, когда я выполняю модульные тесты с помощью JUnit.

ли теоретически возможно, что все WritableByteChannelEndpoint экземпляра уже очищаться и channel устанавливается в нуль, а какой-то другой объект все еще есть (слабая?) Ссылка на него?

+1

Вы уверены, что это не гонка? Создает ли конструктор суперкласса экземпляр вообще? – hexafraction

+0

Да, супер-конструктор переходит к некоторой задаче запуска async. –

+0

ОК, понял. Эта задача async вызывает 'onNext' до того, как дочерний конструктор даже закончил. Если хотите, вы можете написать это как ответ, я бы согласился. –

ответ

3

Перед тем, как заподозрить странное поведение GC через слабые ссылки, рассмотрите более вероятное состояние гонки: ваш конструктор вызывает конструктор суперкласса перед установкой this.channel. Конструктор суперкласса может, следовательно, протекать в соответствии с конструкцией WritableByteChannelEndpoint до this, которая вызывается до того, как конструктор подкласса имеет возможность задать значение channel. Ваше окончательное поле не становится null, так как у него нет возможности быть не нулевым по времени (с перерывами).