A reference to null should never be dereferenced/accessed. Doing so will cause a NullPointerException to be thrown. At
best, such an exception will cause abrupt program termination. At worst, it could expose debugging information that would be useful to an attacker, or
it could allow an attacker to bypass security measures.
Note that when they are present, this rule takes advantage of nullability annotations, like @CheckForNull or @Nonnull,
defined in JSR-305 to understand which values can be null or not. @Nonnull will be
ignored if used on the parameter of the equals method, which by contract should always work with null.
The variable myObject is equal to null, meaning it has no value:
public void method() {
Object myObject = null;
System.out.println(myObject.toString()); // Noncompliant: myObject is null
}
The parameter input might be null as suggested by the if condition:
public void method(Object input)
{
if (input == null)
{
// ...
}
System.out.println(input.toString()); // Noncompliant
}
The unboxing triggered in the return statement will throw a NullPointerException:
public boolean method() {
Boolean boxed = null;
return boxed; // Noncompliant
}
Both conn and stmt might be null in case an exception was thrown in the try{} block:
Connection conn = null;
Statement stmt = null;
try {
conn = DriverManager.getConnection(DB_URL,USER,PASS);
stmt = conn.createStatement();
// ...
} catch(Exception e) {
e.printStackTrace();
} finally {
stmt.close(); // Noncompliant
conn.close(); // Noncompliant
}
As getName() is annotated with @CheckForNull, there is a risk of NullPointerException here:
@CheckForNull
String getName() {...}
public boolean isNameEmpty() {
return getName().length() == 0; // Noncompliant
}
As merge(…) parameter is annotated with @Nonnull, passing an identified potential null value (thanks to @CheckForNull)
is not safe:
private void merge(@Nonnull Color firstColor, @Nonnull Color secondColor) {...}
public void append(@CheckForNull Color color) {
merge(currentColor, color); // Noncompliant: color should be null-checked because merge(...) doesn't accept nullable parameters
}
Ensuring the variable myObject has a value resolves the issue:
public void method() {
Object myObject = new Object();
System.out.println(myObject.toString()); // Compliant: myObject is not null
}
Preventing the non-compliant code to be executed by returning early:
public void method(Object input)
{
if (input == null)
{
return;
}
System.out.println(input.toString()); // Compliant: if 'input' is null, this is unreachable
}
Ensuring that no unboxing of null value can happen resolves the issue
public boolean method() {
Boolean boxed = true;
return boxed; // Compliant
}
Ensuring that both conn and stmt are not null resolves the issue:
Connection conn = null;
Statement stmt = null;
try {
conn = DriverManager.getConnection(DB_URL,USER,PASS);
stmt = conn.createStatement();
// ...
} catch(Exception e) {
e.printStackTrace();
} finally {
if (stmt != null) {
stmt.close(); // Compliant
}
if (conn != null) {
conn.close(); // Compliant
}
}
Checking the returned value of getName() resolves the issue:
@CheckForNull
String getName() {...}
public boolean isNameEmpty() {
String name = getName();
if (name != null) {
return name.length() == 0; // Compliant
} else {
// ...
}
}
Ensuring that the provided color is not null resolves the issue:
private void merge(@Nonnull Color firstColor, @Nonnull Color secondColor) {...}
public void append(@CheckForNull Color color) {
if (color != null) {
merge(currentColor, color); // Compliant
}
}