我正在通过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设置中的异常(在本问题的答案中描述)。
嗨我有以下方法: 不得不提的是,startDate和endDate是长变量。我尝试在if条件中添加null检查,也尝试使用longValue()方法,但没有结果。你知道我怎样才能解决这个问题吗?可能是fndBugs端的bug?
我正在代码中运行findBugs测试。 它报告NP_NULL_ON_SOME_PATH:以下代码中可能存在空指针解引用。 我不明白为什么它会这样报告?
我已经在我的sonar实例上测试了规则“正确性--可能的空指针取消引用”和“正确性--在异常路径的方法中可能的空指针取消引用”。不幸的是,以下代码从未被检测为错误 Netbeans能够正确检测到此问题,但sonar 3.6.1不能。 谢谢你的帮助
问题内容: 我正在android中做一个应用程序,因此我需要访问com.android.internal.telephony API。现在,我可以访问这些API了,但问题是,无论我在自己的类中调用Class Call.java方法的什么地方,都会抛出。您可以在http://hi- android.info/src/com/android/internal/telephony/Call.java.h
风格: 日志消息:10-10 13:20:01.184:E/AndroidRuntime(1417):致命异常:main 10-10 13:20:01.184:E/AndroidRuntime(1417):android。看法WindowManager$BadTokenException:无法添加窗口--android令牌。应用程序。本地活动管理器$LocalActivityRecord@411e