docs/bugpattern/nullness/RedundantNullCheck.md
A null check (e.g., x == null or x != null) is redundant if it is performed
on an expression that is statically determined to be non-null according to
language semantics or nullness annotations. This check can optionally be
configured to flag redundant calls to Objects.requireNonNull(x) as well.
Within a @NullMarked scope, types are non-null by default unless explicitly
annotated with @Nullable. Therefore, checking a variable or method return
value (that isn't @Nullable) for nullness is unnecessary, as it should never
be null.
Example:
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
@NullMarked
class MyClass {
void process(String definitelyNonNull) {
// BUG: Diagnostic contains: RedundantNullCheck
if (definitelyNonNull == null) {
System.out.println("This will never happen");
}
// ...
}
String getString() {
return "hello";
}
@Nullable String getNullableString() {
return null;
}
void anotherMethod() {
String s = getString();
// BUG: Diagnostic contains: RedundantNullCheck
if (s == null) {
// s is known to be non-null because getString() is not @Nullable
// and we are in a @NullMarked scope.
System.out.println("Redundant check");
}
String nullableStr = getNullableString();
if (nullableStr == null) { // This check is NOT redundant
System.out.println("Nullable string might be null");
}
}
}
This check helps to clean up code and reduce clutter by removing unnecessary
null checks, making the code easier to read and maintain. It also reinforces the
contract provided by @NullMarked and @Nullable annotations.
By default, this check only flags redundant null checks using == null and != null. To also flag redundant calls to Objects.requireNonNull(x), enable it
with the following flag:
-XepOpt:RedundantNullCheck:CheckRequireNonNull=true
Suppress false positives by adding the suppression annotation
@SuppressWarnings("RedundantNullCheck") to the enclosing element.