7

JMM によると発生しないはずの奇妙な動作が見られます。クラスAを拡張するクラスBがあります。これは、コンストラクターでクラスBによってアクセスされるコンストラクターで初期化されるAの最終保護フィールドです。

しかし、ごくまれに、B でアクセスすると NPE が発生します。何かアイデアはありますか?

コードの一部:

class AsyncReplicationSourceGroup extends AbstractReplicationSourceGroup{

    public AsyncReplicationSourceGroup(DynamicSourceGroupConfigHolder groupConfig){
        super(groupConfig);
        createReplicationChannels();  
    }

    protected void createReplicationChannels(){
        //...
        specificLogger.finest("created channel");  // this is where the NPE is thrown from
        //...
    }
}

abstract class AbstractReplicationSourceGroup{

    protected final Logger specificLogger;

    public AbstractReplicationSourceGroup(DynamicSourceGroupConfigHolder groupConfigHolder){
        specificLogger = Logger.getLogger(Constants.LOGGER_REPLICATION_GROUP + "." + _groupConfigHolder.getConfig().getName());
        //...
    }

}
4

2 に答える 2

1

単独で投稿されたコードから確実に判断することは不可能ですが、ロガー自体がnullであることが確実である場合(そして、内部からNPEが誤って表示されていない場合、たとえば、specificLogger.finest)、最も可能性の高い説明は次のとおりです。 Logger.getLoggerは、何らかの理由でnullを返すことがあります。

コンストラクター内で参照がリークしない限り、コンストラクターで割り当てられた最終フィールドは、構築されたオブジェクトが表示されると表示されることが保証されるため、問題はスレッド化ではないと思います。

于 2012-06-22T03:25:35.350 に答える
0

あなたの例から判断するのは簡単ではありませんが、私の推測では、ロギング フレームワークと、コンストラクターでそれを初期化するための train-wreck 呼び出しを処理する必要があると思います。これは、ロガー宣言が常にprivate static finalでなければならない理由の 1 つです。

于 2012-06-26T20:53:15.050 に答える