NullPointerException我无法识别

时间:2016-04-05 19:29:36

标签: java concurrency nullpointerexception

我有以下代码片段:

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()抛出。 所以基本上是一个并发问题

1 个答案:

答案 0 :(得分:1)

NPE 只能被&#39;抛出。&#39; (点运算符)取消引用对象。看一下这行,你解除引用的6个变量你不会检查我看到的null:Enumeration1,Enumeration2和Enumeration3以及每个变量的VALUE。如果NPE被抛到等于中,你会看到那条线。

如下面的评论中所述,有例外:

  1. 如果显式抛出NullPointerException,在这种情况下,堆栈跟踪将指向带有throw语句的行。
  2. 自动装箱会导致NPE。从本质上讲,它正在添加&#39;。&#39;点运算符到已编译的代码。这可能很讨厌。根据我的经验,堆栈跟踪将显示从没有代码的奇怪地方抛出的异常(源IIRC的第1行)。