Null Creep
I believe it is really important to clearly specify how your classes react to null values. Suppose some class is buried deep in your application code:
public class Company {
private final String id;
private final String name;
public Company(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public boolean equals(Object o) {
// ...hmm...can id be null? Better write some defensive code:
if (id == null) { ... }
...etc
}
}
Perhaps a class like this represents some fundamental concept and is used throughout an entire family of applications. While reviewing the code, you see the equals(...) method checks for a null id. And you wonder…can the id ever be null?
There Must be a Reason
Surely the original programmer put that null check in for a reason. Or maybe not — maybe he generated the equals() and hashCode() methods using an IDE? There are no comments, and you discover everyone using the Company class also checks for null:
public void connectTo(Company c) {
String id = c.getId();
if (id != null) {
...
}
Maybe the programmer who wrote that method just wasn’t sure — since Company has no comments. So in an effort to “be safe”, he checks for null before using the company id.
Creeping Dread…
And what do you do if the id really is null? Oh, crap. Now you have to throw an exception, and someone has to eventually catch it. Everything from the data access layer on up to the GUI has to anticipate the possible error.
Because the first programmer failed to document how Company handles null, EVERYBODY who uses the Company class now has to assume the id might be null. The fact that the original programmer included some null checking in the Company class seems to imply that it might indeed be null.
A Better Solution
If null really is allowed, that’s fine — you just need to document that fact. But if null really is illegal, then fail fast:
public class Company {
private final String id;
private final String name;
public Company(String id, String name) {
if (id == null) throw new IllegalArgumentException("null id");
if (name == null) throw new IllegalArgumentException("null name");
this.id = id;
this.name = name;
}
...etc
That tiny exception now means everybody using the Company class can eliminate their null checking. Which means instead of potentially checking for null and reacting by throwing NullPointerException from dozens of locations scattered about your app(s), the validation occurs in a single location.
For more fun, check out these @Nullable and @NotNull annotations.


