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?
The reasoning behind using
Objects#requireNonNullis similar to the one behind returningOptional: you do it to manage expectations.Optional<Something>instead of justSomethingyou're saying: "Hey, I know thisSomethingvalue might be missing, so instead of returningnulland letting you guess, I'm returning anOptional<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."Objects.requireNonNull(something)in your code before usingsomething, you're saying: "Hey, if you're reading this, I just wanted you to know that I expect thissomethingparameter 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 callingsomething.contains(...), I'm invokingrequireNonNullright here and now to make it clear (in case any of us missed the@NotNullannotation 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.