Chapter 32. How to Avoid Null

Carlos Obregón

Tony Hoare calls null the “billion-dollar mistake.” It’s a mistake, and that’s why you should get in the habit of forbidding code from using null. If you have a reference to an object that might be null, you have to remember to do a null check before trying to call any method of it. But since there’s no obvious difference between a null reference and a non-null one, it’s too easy to forget and get a NullPointerException

The most future-proof way to avoid issues is to use an alternative when possible.

Avoid Initializing Variables to Null

It is usually not a good idea to declare a variable until you know what value it should hold. For complex initialization, move all the initialization logic to a method. For example, instead of doing this:

public String getEllipsifiedPageSummary(Path path) {
   String summary = null;
   Resource resource = this.resolver.resolve(path);
   if (resource.exists()) {
       ValueMap properties = resource.getProperties();
       summary = properties.get("summary");
   } else {
       summary = "";
   }
   return ellipsify(summary);
}

Do the following:

public String getEllipsifiedPageSummary(Path path) {
   var summary = getPageSummary(path);
   return ellipsify(summary);
}
public String getPageSummary(Path path) {
   var resource = this.resolver.resolve(path);
   if (!resource.exists()) {
      return "";
   }
   var properties = resource.getProperties();
   return properties.get("summary");
}

Initializing a variable to null might leak null unintentionally if you are not careful with your error-handling code. Another developer might change the control flow without realizing the issue—and that other developer might be you three months after the code was first written.

Avoid Returning Null

When you read the signature of a method, you should be able to understand if it always returns a T or if sometimes it doesn’t.  Returning an Optional<T> is a better option that makes the code more explicit. Optional’s API makes it very easy to deal with the scenario where no T was produced. 

Avoid Passing and Receiving Null Parameters

If you need a T, ask for it; if you can get by without one, then don’t ask for it. For an operation that can have an optional parameter, create two methods: one with the parameter and one without. 

For example, the method drawImage from the Graphics class in the JDK has a version that receives five parameters and a sixth parameter, an ImageObserver, which is optional. If you don’t have an ImageObserver, you need to pass null like this:

g.drawImage(original, X_COORD, Y_COORD, IMG_WIDTH, IMG_HEIGHT, null);

It would have been better to have another method with just the first five parameters.

Acceptable Nulls

When is it acceptable to use null, then? As an implementation detail of a class, i.e., the value of an attribute. The code that needs to be aware of that absence of value is contained to the same file, and it’s much more simple to reason about it and not leak null.

So remember, unless you have an attribute, it’s always possible to avoid using null using a superior construct in your code. If you stop using null where you don’t need it, then it becomes impossible to leak null and have a NullPointerException. And if you avoid these exceptions, you’ll be part of the solution to the billion-dollar problem instead of being part of it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.194.39