我通过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;
我觉得有点清楚。如果没有人同意这一变化,我会按照建议做,只是忽略这个问题,即使我宁愿避免这种情况。
答案 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);
}