java.util.Optional – What it is and how to use it – What is java.util.Optional?

java.util.Optional – What it is and how to use it – What is java.util.Optional?

0 0


What it is and how to use it

On Github tginsberg / java-optional


What it is and how to use it

Created by Todd Ginsberg for CJUG 2016-06-02

What is java.util.Optional?

  • Introduced in Java 8
  • Intended to reduce NullPointerExceptions
  • A signal to other developers that a value may not be present
  • Container with zero or one elements

What isn't java.util.Optional?

  • Not capable of storing null
  • Not serializable!
  • Not widely used in the JDK
"Our intention was to provide a limited mechanism for library method return types where there needed to be a clear way to represent "no result", and using null for such was overwhelmingly likely to cause errors." -- Brian Goetz

How did it get here?

Optional is mainly here to make stream terminal operations possible for empty streams.
new ArrayList<String>().stream().findFirst();

Why not also add it to Map?

public interface Map<K,V> {

    // ...

    default Optional<V> getOptionally(K k) {
        // ...
Maps can contain null values!
Map<String, String> map = new HashMap<>();

// Both look the same - no difference between not present and null.


value isEmpty() isPresent() .get() not null false true value null true false NoSuchElementException


Use one of the two built-in Factory methods
Optional<String> text = Optional.ofNullable("Hello, world!");


Optional<String> text = Optional.of(somethingThatIsntNull);
Optional<String> text = Optional.of(null);
// -> NullPointerException

When to use it

If you use it at all, only use it for return types where there is no natural way to represent "no result"
// Yes
public Optional<Customer> getCustomerById(long id);
// No
public Optional<List<Customer>> getCustomersForMonth(final YearMonth when);
// Prefer:
public List<Customer> getCustomersForMonth(final YearMonth when);
// -> Collections.emptyList();

Don't call .get()!

Optional<String> text = service.getText();
if(text.isPresent()) {
} else {
    System.out.println("Hello, world!");
Looks just like...
String text = service.getText();
if(text != null) {
} else {
    System.out.println("Hello, world!");
"In retrospect, we should have called get something like getOrElseThrowNoSuchElementException or something that made it far clearer that this was a highly dangerous method that undermined the whole purpose of Optional in the first place. Lesson learned." -- Brian Goetz

Use one of the safe methods instead!

Optional<String> text = service.getText();
System.out.println(text.orElse("Hello, world!"));
Optional<String> text = service.getText();
Optional<String> text = service.getText();

When not to use it

  • Method parameters
  • Fields
  • In any DTO or Entity, because it is not serializable
  • If your customers are not using Java 8
  • Possibly, don't use it at all!

Rules to remember

  • When returning them, make absolutely sure they aren't null
  • Don't call .get()