我看到一个奇怪的行为,根据JMM似乎不应该发生。
我有扩展了类A的类B,这是类A中的最后一个 protected 字段,它是在类B的构造函数访问的构造函数中初始化的。

但是,在极少数情况下,使用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());
        //...
    }

}

最佳答案

从单独发布的代码中无法确定,但是如果您确定记录器本身为空,(并且您没有从内部错误地看到NPE,例如specificLogger.finest),那么最可能的解释是Logger.getLogger出于某种原因偶尔返回null。

我认为问题不在于线程化,因为只要在构造函数内部没有引用泄漏,只要构造对象可见,就可以保证在构造函数中分配的最终字段是可见的。

08-04 00:45