我有以下代码片段:
List<SomeObject> allObjects = getNotNullCollection(SomeObject.class, getExpression());
Enumeration2Child mightBeNull = getEnumeration2();
try {
for (SomeObject someObject : allObjects) {
if (someObject == null) {
LOGGER.warn("Null Object " + getId() + " expression : " + getExpression().toString());
StringBuilder errorMsg = new StringBuilder();
for (Object element : allObjects) {
errorMsg.append(element != null ? element.toString() : "Null").append(" - ");
}
LOGGER.warn("allObjects: ", errorMsg.toString());
return false;
}
if (someObject.getValue() != null && someObject.getValue().equals(Enumeration1.VALUE) && !(Enumeration2.VALUE2.equals(mightBeNull) || Enumeration2.VALUE3.equals(mightBeNull))) {
return false;
}
}
} catch (NullPointerException e) {
}
并且有一个NPE排队:
if (someObject.getValue() != null && someObject.getValue().equals(Enumeration1.VALUE) && !(Enumeration2.VALUE2.equals(mightBeNull) || Enumeration2.VALUE3.equals(mightBeNull)))
正如你在上面看到的,我检查someObject是否为null,我还检查someObject.getValue()是否为null,所以我应该在这部分是安全的。 而其余的if语句只是等于调用(然后我假设我会在equals方法中得到NPE而不是在if语句中)。 我想念这里还有什么可能是错的? 谢谢
编辑:您好,请关闭此问题。你确实是对的,我没有注意到关键信息,但最初很难调查。我添加了额外的日志记录,发现有3个线程执行相同的代码。 现在,这不会是一个问题,但是由于实现了DB缓存,返回allObjects的getExpression()在这些线程之间共享。当一个人检查此片段中的空值时: 'if(someObject.getValue()!= null&amp;&amp; someObject.getValue()。' 第一次检查返回不是Null然后另一个线程擦除了值,因此NPE被someObject.getValue()抛出。 所以基本上是一个并发问题答案 0 :(得分:1)
NPE 只能被&#39;抛出。&#39; (点运算符)取消引用对象。看一下这行,你解除引用的6个变量你不会检查我看到的null:Enumeration1,Enumeration2和Enumeration3以及每个变量的VALUE。如果NPE被抛到等于中,你会看到那条线。
如下面的评论中所述,有例外: