简体   繁体   中英

What is the correct way to implement compareObjects()

I have compareObjects method implemented as below

public static int compareObjects(Comparable a, Comparable b){

        if (a == null && b == null){
            return 0;
        } else if (a == null && b != null){
            return -1;
        } else if (a != null && b == null){
            return 1;
        } else {
            return a.compareTo(b);
        }
    }

When I run this through findBugs, I get this suggestion on the line return a.compareTo(b) :

There is a branch of statement that, if executed, guarantees that a null value will be dereferenced, which would generate a NullPointerException when the code is executed. Of course, the problem might be that the branch or statement is infeasible and that the null pointer exception can't ever be executed; deciding that is beyond the ability of FindBugs. Due to the fact that this value had been previously tested for nullness, this is a definite possibility.

At this point a can never be null. Why does FindBugs show me this suggestion? How can I correct this; what is the correct way to implement compareObjects() ?

It may be a limitation in FindBugs; I agree that you've covered all the bases, but your null-check is split across two different conditions. Now these conditions happen to be complementary, so at least one of them will fire if a is null, but depending how sophisticated FindBugs is, it may not recognise this.

Two options here, then:

  1. Just ignore the FindBugs warning. Due to its nature it will raise some false positives from time to time, so don't feel like you have to rewrite your code to make it 100% happy if you don't think the rewrite is worthwhile on its own merits.

    You can use the @SuppressWarnings annotation to actually communicate this to FindBugs, if you want the report to show a nice big zero at the end. See this question for an example.

  2. Restructure the condition so that the nullity check on a is more explicit, by nesting if blocks:

     if (a == null) { return b == null ? 0 : -1; } return b == null ? 1 : a.compareTo(b); 

    Depending on your tastes and style that might be a better rewrite anyway, in that is more clearly says "if a is null, do this calculation and return it, otherwise do this calculation". You can of course change the ternary condition into another if-else block if you prefer that.

I think it might be because you don't need the extra && statements. After the first if statement you already know that one of them is null.

public static int compareObjects(Comparable a, Comparable b){

    if (a == null && b == null){
        return 0;
    } else if (a == null){
        return -1;
    } else if (b == null){
        return 1;
    } else {
        return a.compareTo(b);
    }
}

Looking at it again , try this code:

if (a == null && b == null){
    return 0;
} 

if (a == null){
    return -1;
} 

if (b == null){
    return 1;
} 

return a.compareTo(b);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM