【发布时间】:2016-04-05 19:29:36
【问题描述】:
我有以下代码片段:
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 是否为空,我还检查 someObject.getValue() 是否为空,所以我在这部分应该是安全的。 其余的 if 语句只是 equals 调用(然后我假设我会在 equals 方法中而不是在 if 语句中获得 NPE)。 我在这里想念的还有什么问题? 谢谢
编辑:您好,让我们结束这个问题。您确实是对的,我没有注意到关键信息,但最初很难调查。我添加了额外的日志记录,发现有 3 个线程执行相同的代码。 现在,这不是问题,但由于实现了返回 allObjects 的 DB 缓存 getExpression(),在这些线程之间共享。当检查此片段中的空值时: 'if (someObject.getValue() != null && someObject.getValue().' 第一次检查返回的不是 Null,然后另一个线程删除了该值,因此 someObject.getValue() 抛出了 NPE。 所以基本上是并发问题
【问题讨论】:
-
我认为您也没有向我们提供足够的信息来识别它。你读过这个吗? stackoverflow.com/q/218384/3973077
-
您也可以检查
Enumeration1.VALUE,或者mightBeNull实际上为空?? -
你至少应该包含调用栈。
-
mightBeNull 为 null,但在这种情况下,可能会在 equals 方法中引发异常,而不是在此 if 语句中,因此堆栈跟踪看起来会有所不同
标签: java concurrency nullpointerexception