Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using StringUtils.isEmpty without losing compiler warnings about null pointers

Instead of the usual if (myString == null || myString.equals("")) I tend to prefer using the org.apache.commons.lang.StringUtils class and do if (StringUtils.isEmpty(myString)).

However this - at least the way I'm doing it - comes with a gigantic downside: because FindBugs - or the compiler warning mechanism, f. ex. from Eclipse - will no longer see the explicit null-check, it will no longer consider myString as potentially null, so it will no longer raise the warnings about potential (or sure) null pointers on it, and those warnings are extremely useful in my view.

Example (ADDED):

import org.apache.commons.lang.StringUtils;

public class TestWarning
{
    void testWarning(String myString)
    {
        //if (myString == null || myString.equals("")) // With this, the last line shows the warning.
        if (StringUtils.isEmpty(myString)) // With this, no warning.
        {
            // Anything.
        }
        int x = myString.length(); // Warning is here: "Potential null pointer access: The variable myString may be null at this location"
    }
}

So I'm just trying to make sure that there is no way to eliminate or minimize this downside so that one can use StringUtils.isEmpty and still get the null pointer warnings. Maybe some annotation like @Nullcheck to add to the isEmpty method or something else ?

ADDED: For ex., would it be feasible to create a custom annotation like @Nullcheck, add it to the arg of isEmpty like public static boolean isEmpty(@Nullcheck String str) just to indicate that the method does a null-check on that arg, and make so that the compiler warning mechanism or FindBugs treat a if (StringUtils.isEmpty(myString)) just like an explicit null-check ?

like image 488
SantiBailors Avatar asked Jun 05 '14 09:06

SantiBailors


3 Answers

If you annotate myString with @Nullable, i.e.

void testWarning(@Nullable String myString)

then at least eclipse will report a warning when you dereference it.

I agree that FindBugs should also be warning about it, but I can't get it to do so either.

like image 68
TimK Avatar answered Sep 25 '22 12:09

TimK


Whether you get a potential null pointer warning really depends on how good the static code analyzer is. Logically, if you use

if (myString == null || myString.equals(""))

your code expect myString to be null. In the subsequent line, however, you dereference myString. The static code analyzer sees these two facts, and create a null pointer warning.

If you use

if (StringUtils.isEmpty(myString))

your code does not say whether it expects myString to be null. The static code analyzer, thus, does not generate a null pointer warning. The static code analyzer can certainly choose to generate a null pointer warning, but this will produce a lot of false positives, because it needs to assume that inputs to any method may be null.

like image 32
fajarkoe Avatar answered Sep 26 '22 12:09

fajarkoe


The Eclipse code analysis can also evaluate external null annotations (since 4.5.0). More information is available at https://wiki.eclipse.org/JDT_Core/Null_Analysis/External_Annotations.

like image 37
Konrad Windszus Avatar answered Sep 26 '22 12:09

Konrad Windszus