How to tell IDEA/Studio that the null check has be

2019-01-24 10:54发布

问题:

I'm developing with Android Studio/IntelliJ IDEA.

I have enabled the inspection check called "Constant conditions & exceptions" that shows a warning if I am risking a NPE, such as:

String foo = foo.bar(); // Foo#bar() is @nullable
if (foo.contains("bar")) { // I'm living dangerously
    ...
}

I have the following in my code:

String encoding = contentEncoding == null ? null : contentEncoding.getValue();
if (!TextUtils.isEmpty(encoding) && encoding.equalsIgnoreCase("gzip")) {
    inputStream = new GZIPInputStream(entity.getContent());
} else {
    inputStream = entity.getContent();
}

Here's the source code of TextUtils#isEmpty(String):

/**
 * Returns true if the string is null or 0-length.
 * @param str the string to be examined
 * @return true if str is null or zero length
 */
public static boolean isEmpty(CharSequence str) {
    if (str == null || str.length() == 0)
        return true;
    else
        return false;
}

I'm not risking any NPE because TextUtils#isEmpty(String) would return true to a null pointer.

However I'm still getting the little Method invocation 'encoding.equalsIgnoreCase("gzip")' may produce 'java.lang.NullPointerException' warning, which can be annoying.

Is it possible to make this check smarter and ignore the NPE warning if there's already a null-check done?

回答1:

You can look into the link that Peter Gromov mention in his answer.

Created some simple classes that resemble your setup:

A class with a method annotated with @Nullable:

The TextUtil class with it's isEmpty method:

And finally the main class calling the TextUtil#isEmpty:

Now if you enter the File -> Settings... and go to Inspections ->Constant conditions & exceptions part you can change the Configure Assert/Check Methods to cater for your isEmpty method:

Add a new IsNull check method:

Enter the TextUtil class, isEmpty method and CharSequence parameter:

This gives this Assert/Check Method Configuration window:

Press Ok and then Ok again to go back to the editor view and you'll see that the inspection disappeared:

You are actually telling IntelliJ that the isEmpty method is doing a null check on the str parameter.



回答2:

You could use //noinspection ConstantConditions that will remove the NPE warning for the following line, like this:

String encoding = contentEncoding == null ? null : contentEncoding.getValue();

//noinspection ConstantConditions
if (!TextUtils.isEmpty(encoding) && encoding.equalsIgnoreCase("gzip")) {
    inputStream = new GZIPInputStream(entity.getContent());
} else {
    inputStream = entity.getContent();
}


回答3:

you can use @SuppressWarnings("ConstantConditions") annotation

@SuppressWarnings("ConstantConditions")
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int indexViewType) {
    if (inflater == null) {
        inflater = LayoutInflater.from(parent.getContext());
    }
    ItemViewProvider provider = getProviderByIndex(indexViewType);
    provider.adapter = MultiTypeAdapter.this;
    return provider.onCreateViewHolder(inflater, parent);
}


回答4:

See http://www.jetbrains.com/idea/webhelp/configuring-check-assert-methods.html for IDEA 12. In IDEA 13 EAP, you can add method contract: http://youtrack.jetbrains.com/issue/IDEA-93372



回答5:

Unfortunately marked as "right answer" solution is of date. But I found equivalent for me solution.

The new versions of IDE work correctly with static methods. So the example from the question won't throw warning anymore.

TextUtils#isEmpty(String);

public static boolean isEmpty(CharSequence str) {
    // your checks
}