声纳严重违规 - 对先前取消引用的值进行空检查

Sonar critical violation - Nullcheck of value previously dereferenced

提问人:rickygrimes 提问时间:11/4/2014 最后编辑:rickygrimes 更新时间:9/15/2022 访问量:26912

问:

对于我在一个测试类中的以下代码,Sonar 向我抛出了一个严重的违规 - 正确性 - 先前取消引用的值的 Nullcheck

 if (testLst != null && !testLst.isEmpty()) {
        for (Test test : testLst) {
            if (test.getName().equalsIgnoreCase("TEST")) {
            // do blah
            }

有人可以说明我在这里做错了什么吗?

编辑:这里的一个答案表明这是因为我以前可以访问该变量,因此 null 检查是多余的。但事实并非如此。这是我的 null 检查之前的代码行。

 testLst = myTest.getValues(); //I am basically populating the array by doing a get, but I am not accessing the list itself by doing a get on it directly - like testLst.get()
 if (testLst != null && !testLst.isEmpty()) {
            for (Test test : testLst) {
                if (test.getName().equalsIgnoreCase("TEST")) {
                // do blah
                }
爪哇岛

评论

1赞 11/4/2014
请发布更多代码,您发布的内容之上有什么?
0赞 11/4/2014
另请参阅 dev.eclipse.org/sonar/rules/show/...
0赞 Dancrumb 11/4/2014
钢筋混凝土。是对的:我们需要看到这个代码前面的代码,直到方法的开头或声明 ;哪个最接近此代码段。testList
0赞 rickygrimes 11/4/2014
这是我的方法中唯一的代码。在此之前什么都没有。
4赞 Ben 2/23/2015
对不起,如果我来得太晚了,但我今天遇到这个问题时注意到的是,声纳实际上突出显示了会导致第一个 NPE 的线路,而不是您进行冗余空检查的线路。就我而言,冗余的 null 检查在代码的下方。

答:

14赞 M A 11/4/2014 #1

当您检查变量的值是否为 null(在本例中)时,会显示此消息,而您之前已经访问过该变量。不需要 null 检查,因为如果值为 null,则会抛出 a。testLstNullPointerException

例:

testLst.remove(something);
if (testLst != null && !testLst.isEmpty()) {
    for (Test test : testLst) {
       if (test.getName().equalsIgnoreCase("TEST")) {
        // do blah
        }

该检查是多余的,因为在程序到达语句时,不能为 null,否则前一条语句会抛出 .在这种情况下,您应该在访问 之前将 null 检查放在 可以为 null 的位置:testLst != nulliftestLsttestLst.remove(something)NullPointerExceptiontestLst

if(testLst != null) {
   testLst.remove(something);
   if (!testLst.isEmpty()) {
       for (Test test : testLst) {
          if (test.getName().equalsIgnoreCase("TEST")) {
           // do blah
          }

评论

1赞 rickygrimes 11/4/2014
对不起,我不明白。您非常接近错误的声纳文档所说的内容。这部分我不清楚 - 当您检查变量的值是否为 null(在本例中为 testLst)而您之前已经访问过该变量时,会显示此消息。你能详细解释一下,这样我就可以接受你的回答了吗?
1赞 rickygrimes 11/4/2014
我接受了答案,但你在这里说的不适用于我的情况。
1赞 M A 11/4/2014
你能发布一些在语句之前存在的代码吗?应该有一个地方,一个变量被取消引用,然后检查它的值是否为空......if
1赞 rickygrimes 11/4/2014
我只是做了。请看一下我的编辑。我的方法上面只有那一行。就是这样。在此之前什么都没有。
0赞 M A 11/4/2014
这很奇怪。如果真的是这样,那么这只是一个错误检测。
-1赞 Mickaël Guerin 3/4/2016 #2
testLst = myTest.getValues(); //I am basically populating the array by doing a get, but I am not accessing the list itself by doing a get on it directly - like testLst.get()
if (testLst != null && !testLst.isEmpty()) {
    for (Test test : testLst) {
        if (test.getName().equalsIgnoreCase("TEST")) {
        // do blah
        }

您是否检查了 myTest != null ? 否则声纳会抛出我猜的严重违规行为。

2赞 Chry007 7/2/2018 #3

我知道我对 OP 来说为时已晚,但也许其他人可能会觉得这很有帮助:

Sonarqube 在行上抛出此错误,这将导致初始 NPE,而不是包含冗余 null 检查的行(错误消息另有指示)

对于 OP:

testLst = myTest.getValues();

我猜getValues()从不返回null,因此testLst不能为null,而只能在null检查时为空。