我看到一种奇怪的行为似乎不应该根据JMM发生。 我有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());
//...
}
}
答案 0 :(得分:1)
单独发布的代码是不可能确定的,但是如果你确定记录器本身是空的,(并且你没有错误地从内部看到NPE,具体说来是具体的Logger.finest),那么最有可能解释是Logger.getLogger由于某种原因偶尔会返回null。
我不认为问题是线程,因为只要构造函数内没有引用泄漏,一旦构造对象可见,构造函数中赋值的最终字段就会保证可见。
答案 1 :(得分:0)
从您的示例中判断并不是很容易,但我的猜测是它必须处理日志框架和train-wreck调用以在构造函数中初始化它。这是记录器声明应始终为私有静态最终
的原因之一