I have an interface with a method like this:
public interface MyInterface {
void myMethod(@Nonnull String userEmail);
}
The interface has the following implementation:
public class MyInterfaceImpl implements MyInterface {
@Override
public void myMethod(@Nonnull String userEmail) {
if ((userEmail== null) || !userEmail.endsWith("something")) {
throw new SomeException("...");
}
...
}
}
The compiler is raising me a warning saying that Condition 'userEmail == null' is always 'false', but that doesn't look right.
As for my understanding, the annotation javax.annotation.Nonnull will warn the compiler in case someone calls my method with a null value, but does not prevent the code to compile if someone passes a null value to it. So yes, my code can be called with a null value at some point:


Note that I get the same warning if I compile on command line with the option -Xlint:all (so it does not look like just a bug in my IDE).
Does anyone have any idea how can I get rid of this warning and why is it occurring?
Disclaimer: the example I showed is just an example, the actual code does some stuff before to get to that condition, but nothing that can make userEmail == null always false (as it's proven by the debugger screenshot that I attached).
As a lot of people mentioned in the comments already. It is behaving as it is intended. The explanation from https://checkerframework.org/manual/#nullness-checker clearly states what is going on here:
The checker issues a warning in these cases: When an expression of @NonNull type might become null, because it is a misuse of the type: the null value could flow to a dereference that the checker does not warn about.
The above warning only shows up when you pass -Alint=redundantNullComparison to the compiler and is by default turned off. As you are compiling with -Xlint:all even this warning is being enabled.
If you don't want to see this warning on itellij you can update your settings:
Settings (Ctrl+Alt+S / ⌘) > Editor > Inspections > Java > Declaration redundancy > Null-check method is called with obviously non-null argument.
or
Settings (Ctrl+Alt+S / ⌘) > Build, Execution, Deployment > Compiler > Add runtime assertions for not null annotated methods and parameters
or
Settings (Ctrl+Alt+S / ⌘) > Editor > Inspections > Java > Probable bugs
Also if you are expecting a null value, it doesn't seem right to use that annotation in the first place.
You have the annotation on the method parameter. @Nonnull String userEmail
So it expects that userEmail== null will always evaluate to false and hence no reason to be there in that if check.
Check the following answer regarding the @Nonnull which belongs to JSR 305
305 is about new annotations where you can already put them, which can help provide programmatic visibility into a design by contract system. So that if a certain method is supposed to not return null, or if a certain method is supposed to never receive a null parameter
So if you as a programmer have the confidence to annotate that parameter as nonNull, why shouldn't it report that the check userEmail == null has no meaning? With the annotation is like you inform the compiler that you have the confidence that it will never get called with null.
Annotation @Nonnull is like describing a contract. You don't make contracts which you know could be broken. If you are not sure then remove the annotation. If you are sure then remove the check userEmail == null
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With