Java 为什么findbugs在此代码中抛出空指针解引用?

Java 为什么findbugs在此代码中抛出空指针解引用?,java,findbugs,Java,Findbugs,我正在通过Sonarqube在我们的代码上运行findbugs,我得到一个空指针解引用错误: 有一个语句分支,如果执行,它保证 空值将被取消引用 故障代码如下所示: public static boolean isBigDecimalDifferent(BigDecimal x, BigDecimal y) { return (x != null || y != null) && ((x != null && y =

我正在通过Sonarqube在我们的代码上运行findbugs,我得到一个空指针解引用错误:

有一个语句分支,如果执行,它保证 空值将被取消引用

故障代码如下所示:

public static boolean isBigDecimalDifferent(BigDecimal x, BigDecimal y) {
        return (x != null || y != null)
                && ((x != null && y == null) || (x == null && y != null) || x.compareTo(y) != 0);   
}
我想知道这怎么可能。唯一可以使用NPE的地方是调用x.compareTo(y),但是如果x=null,Java将永远不会分析该分支,对吗

这是一个bug,还是我遗漏了Java分析这条语句的方法


更新

谢谢你的意见。最后我建议他们把它改成:

if (x!=null && y != null)
    return x.compare(y);
else
    return x!=y;

我觉得更清楚一点。如果没有人同意更改,我会按照建议做,忽略这个问题,尽管我宁愿避免这样做。

我会这样写:

public static boolean isBigDecimalDifferent(BigDecimal x, BigDecimal y) {
   if (x == null) throw new IllegalArgumentException("x cannot be null");
   if (y == null) throw new IllegalArgumentException("y cannot be null");
   return (x.compareTo(y) != 0);
}
我认为它更容易阅读

如果你不想在例外中表达前提条件,我想说这也更清楚:

public static boolean isBigDecimalDifferent(BigDecimal x, BigDecimal y) {
   if (x == null) return (y != null);
   if (y == null) return (x != null);
   return (x.compareTo(y) != 0);
}

这个逻辑对于FindBugs来说太复杂了,它在这里弄错了。你是对的,你在该代码中对去引用
null
进行了辩护

我会简化它,让FindBugs理解它,让任何后续的人类读者也能轻松了解它在做什么:

public static boolean isBigDecimalDifferent(BigDecimal x, BigDecimal y) {
    if (x == null) {
        return y != null;
    }
    if (y == null) {
        return x != null;
    }
    return x.compareTo(y) != 0;
}

旁注:通常,您会有一个方法来检查是否相等,并使用
如果要检查不平等性


你在评论中说:

不幸的是,我没有权限更改遗留代码(我真希望我可以!)


然后,您必须注意FindBugs无法解决这个问题,并在FindBugs设置()中将其作为一个例外。

简单吗?这段代码并不简单。它很难阅读和理解。我会重构它。除非x为null,y不是null,否则你想测试什么?我认为FindBugs因为所有的布尔检查而变得混乱,我找不到一条通向NPE的路径。尝试重构代码。代码很糟糕,但在逻辑上是空安全的。虽然很可怕。是的,我完全同意,我必须做一个布尔表,以确保它试图做什么。不幸的是,我无权更改遗留代码(我真希望可以!)@davidorenzomarino:throwin一个意外的异常,或者一个可以预见的异常。。。