7

我看到了一个奇怪的行为,根据 JMM 似乎不应该发生。我有扩展类 A 的 B 类,A 中的最终受保护字段在 A 构造函数中初始化,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());
        //...
    }

}
4

2 回答 2

1

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

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

于 2012-06-22T03:25:35.350 回答
0

从您的示例中很难看出这一点,但我的猜测是它必须处理日志记录框架和 train-wreck 调用才能在构造函数中对其进行初始化。这是 logger 声明应该始终是private static final的原因之一

于 2012-06-26T20:53:15.050 回答