NullPointerException 我无法识别 [重复]

Posted

技术标签:

【中文标题】NullPointerException 我无法识别 [重复]【英文标题】:NullPointerException I cannot identify [duplicate] 【发布时间】: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。 所以基本上是并发问题

【问题讨论】:

我认为您也没有向我们提供足够的信息来识别它。你读过这个吗? ***.com/q/218384/3973077 您也可以检查Enumeration1.VALUE,或者mightBeNull 实际上为空?? 你至少应该包含调用栈。 mightBeNull 为 null,但在这种情况下,可能会在 equals 方法中引发异常,而不是在此 if 语句中,因此堆栈跟踪看起来会有所不同 【参考方案1】:

NPE 只能被 '.' 抛出(点运算符)取消引用对象。查看该行,有 6 个您正在取消引用的变量,您不检查我看到的 null:Enumeration1、Enumeration2 和 Enumeration3 以及每个变量的 VALUE。如果将 NPE 放在等号内,您会看到该行。

正如下面评论中所指出的,这也有例外:

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

【讨论】:

"NPE 只能由 '.' 抛出(点运算符)”这不是真的。 throw new NullPointerException(); 没有点,Integer v = null; v *= 2; 也没有。 你是对的,但枚举值是我代码中的静态字段。 静态字段可以设置为空。尝试将此添加到代码中:System.out.println("any null? " + (Enumeration1 == null || Enumeration2 == null || Enumeration3 == null)); 这是我的计划。只是部署变更需要时间。

以上是关于NullPointerException 我无法识别 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

NullPointerException 我无法识别 [重复]

无法修复片段 NullPointerException 中的地图片段

RuntimeException:无法启动接收器“包名”:NullPointerException

Spring HttpMessageNotWritableException 无法写入 JSON,NullPointerException

Android Studio:无法启动活动 java.lang.NullPointerException [重复]

登录 NullPointerException 时 Spring Security 无法访问 userService