Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IntelliJ inspection: 'Method invocation may produce NullPointerException'. Does the suggested fix make sense?

I commonly come across the following IntelliJ inspection

private boolean bar() {    
    return foo().contains("foo"); // Method invocation 'contains' may produce 'java.lang.NullPointerException'
}

private String foo() {
    return null;
}

The inspections seem fine to me, but one of (or often times the only) suggested fix from IntelliJ is this:

private boolean bar() {
    return Objects.requireNonNull(foo()).contains("foo");
}

The warning is then gone. But I don't understand how this helps at all? requireNonNull will just throw the same NullPointerException that would have been thrown anyhow when .contains was invoked on null.

Usually, IntelliJ makes meaningful suggestions, and this is a common one, so am I missing the point here?

like image 621
A1m Avatar asked Mar 21 '19 03:03

A1m


People also ask

What happens when you suppress an inspection in IntelliJ?

After you suppress an inspection, IntelliJ IDEA adds a new element before the selected symbol. For example in Java, if you suppress an inspection for a class, a method, or a field, the IDE adds the @SuppressWarnings annotation.

What is the use of NullPointerException in IntelliJ IDEA?

They help you control contracts throughout method hierarchies, and if IntelliJ IDEA spots that the contract is being violated, it will report the detected problem, and will point to the code where NullPointerException may occur.

Can a method return NULL in IntelliJ?

A method should not return null Variables (fields, local variables, and parameters) cannot hold a null value IntelliJ IDEA warns you if these contracts are violated. The @NotNull annotation of the parent method requires the @NotNull annotation for the child class method.

What is @notnull annotation in IntelliJ?

@NotNull. The @NotNull annotation is, actually, an explicit contract declaring that: IntelliJ IDEA warns you if these contracts are violated. The @NotNull annotation of the parent method requires the @NotNull annotation for the child class method.


1 Answers

The reasoning behind using Objects#requireNonNull is similar to the one behind returning Optional: you do it to manage expectations.

  • When you return Optional<Something> instead of just Something you're saying: "Hey, I know this Something value might be missing, so instead of returning null and letting you guess, I'm returning an Optional<Something> instead to make it clear that you should expect it to maybe not be there, and that I expect you to check if it's there before using it."
  • When you call Objects.requireNonNull(something) in your code before using something, you're saying: "Hey, if you're reading this, I just wanted you to know that I expect this something parameter to not be null, and that I expect you to make sure it isn't before calling this code; so instead of just trusting you and outright calling something.contains(...), I'm invoking requireNonNull right here and now to make it clear (in case any of us missed the @NotNull annotation in the method declaration)."

Does it solve the problem? No, it doesn't. IntelliJ cannot magically forbid a parameter from being null. But it can force anybody reading that code to be aware that the parameter is not supposed to be null, and to reason about scenarios where that might happen.

like image 129
walen Avatar answered Oct 21 '22 18:10

walen