我看到一个奇怪的行为,根据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。
我认为问题不在于线程化,因为只要在构造函数内部没有引用泄漏,只要构造对象可见,就可以保证在构造函数中分配的最终字段是可见的。