What is the point of Optionals?

Series: growth March 17, 2015

There is a problem with null (or nil or undefined). It has a tendency to propagate throughout your code. Excessive null checking is a sign of unconfident code — “I’m not sure if this could even be null, might as well check for it…just in case”.

One pattern that developers reach for to help with this is the Optional class.

So some code like this:

public MachineStats getMachineStatsById(int id) {
    Machine machine = machineService.getMachine(id);
    
    if (machine != null) {
        return machine.getStats();
    } else {
        throw new EntityNotFoundExpection();
    }
}

Becomes this:

public MachineStats getMachineStatsById(int id) {
    Optional<Machine> machine = machineServive.getMachine(id);
    
    if (machine.isPresent()) {
        return machine.getStats();
    } else {
        throw new EntityNotFoundExpection();
    }
}

At first glance, all that we’ve done is swap a null check for a call to .isPresent(), so what’s the point? Is this just “Patterns for Patterns Sake”?

I wondered this myself. Like for a long time.

But after listening to an episode of the Giant Robots podcast on Haskell’s Maybe data type, I finally understood why you would prefer Optional over null.

It’s all about being expressive.

By returning an Optional, you are being explicit that the value could be null. This loosely enforces a contract — if a method returns an Optional, the caller should handle the absent case. If a method returns an unwrapped type, then it should be assumed to never be null.

I can’t speak for Haskell, but at least in Java, this contract has to be more of a convention than a strict enforcement.

But if we follow this convention (and spread this knowledge among the team), we can drastically reduce the need for the defensive null checks that are so frequently sprinkled throughout a codebase.

public MachineStats getMachineStatsById(int id) {
    Machine machine = machineService.getMachine(id);
    return machine.getStats();
}

At the end of the day, using Optional is more than just a band-aid for covering up NullPointerExceptions, it is a mechanism to better communicate how your code works to others.


built with , Jekyll, and GitHub Pages — read the fine print