239. Do not use Optional in method args

The do not use category continues with another common mistake of using Optional. This time let's address the usage of Optional in method arguments.

Using Optional in method arguments is just another use case that may lead to code that is unnecessarily complicated. Mainly, it is advisable to take responsibility for null-checking arguments instead of trusting that the callers will create Optional classes, especially empty Optional classes. This bad practice clutters the code and is still prone to NullPointerException. The caller can still pass null. So you have just turned back to checking null arguments.

Keep in mind that Optional is just another object (a container) and is not cheap. Optional consumes four times the memory of a bare reference!

As a conclusion, think twice before doing something like the following:

// Avoid
public void renderBook(Format format,
Optional<Renderer> renderer, Optional<String> size) {

Objects.requireNonNull(format, "Format cannot be null");

Renderer bookRenderer = renderer.orElseThrow(
() -> new IllegalArgumentException("Renderer cannot be empty")
);

String bookSize = size.orElseGet(() -> "125 x 200");
...
}

Check the following call of this method that creates the required Optional class. But, obviously, passing null is possible as well and will result in NullPointerException, but this means that you intentionally defeat the purpose of Optional—don't think of polluting the preceding code with null checks for the Optional parameters; that would be a really bad idea:

Book book = new Book();

// Avoid
book.renderBook(new Format(),
Optional.of(new CoolRenderer()), Optional.empty());

// Avoid
// lead to NPE
book.renderBook(new Format(),
Optional.of(new CoolRenderer()), null);

We can fix this code by removing Optional classes as follows:

// Prefer
public void renderBook(Format format,
Renderer renderer, String size) {

Objects.requireNonNull(format, "Format cannot be null");
Objects.requireNonNull(renderer, "Renderer cannot be null");

String bookSize = Objects.requireNonNullElseGet(
size, () -> "125 x 200");
...
}

This time, the call of this method doesn't force the creation of Optional:

Book book = new Book();

// Prefer
book.renderBook(new Format(), new CoolRenderer(), null);
When a method can accept optional parameters, rely on old-school method overloading, not on Optional.
..................Content has been hidden....................

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