为什么findbugs会在此代码中抛出空指针取消引用?

时间:2016-01-05 10:39:26

标签: java findbugs

我通过Sonarqube在我们的代码上运行了findbugs,并且我在空指针取消引用时遇到错误:

  

有一个声明分支,如果执行,则保证a   空值将被取消引用。

错误的代码就是这样:

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永远不会分析那个分支,对吗?

这是一个错误,还是我错过了Java分析此声明的方式?

更新

感谢您的投入。我最后建议他们将其更改为:

if (x!=null && y != null)
    return x.compare(y);
else
    return x!=y;
我觉得有点清楚。如果没有人同意这一变化,我会按照建议做,只是忽略这个问题,即使我宁愿避免这种情况。

2 个答案:

答案 0 :(得分:5)

逻辑对于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设置(described in this question's answers)中将其作为例外。

答案 1 :(得分:0)

我会这样写这个方法:

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);
}
相关问题