Skip to content

Optionals (course memo)

Java. Sometimes a method has nothing to return (an empty list, an element that wasn't found). Optional is a box: if there's something to return, it's placed in the box; if not, the box is left empty — but a box (the Optional itself) is always returned. A method returning Optional signals to callers that it might not have anything to give back, and forces them to check before using the result.

Before / after

java
public class SongRandomizer {
    public Song pickOneRandom(List<Song> songs) {
        if (songs.isEmpty()) {
            return null; // bad practice!
        }
        List<Song> copy = new ArrayList<>(songs);
        Collections.shuffle(copy);
        return copy.get(0);
    }
}
java
public class SongRandomizer {
    public Optional<Song> pickOneRandom(List<Song> songs) {
        if (songs.isEmpty()) {
            return Optional.empty(); // good practice!!
        }
        List<Song> copy = new ArrayList<>(songs);
        Collections.shuffle(copy);
        Song song = copy.get(0);
        return Optional.of(song); // good practice!!
    }
}

Creating Optionals

  • Return type: Optional<T>, with the diamond operator specifying the type normally returned.
  • Optional.empty() when there's nothing to return.
  • Optional.of(object) to wrap the object that would normally be returned.
  • Can't use new + a constructor to create an Optional — only the static factory methods Optional.of / Optional.empty.

Using Optionals

java
public class MusicPlayer {
    private SongRandomizer songRandomizer = new SongRandomizer();

    public void playOneAtRandom(List<Song> songs) {
        Optional<Song> oSong = songRandomizer.pickOneRandom(songs);
        if (oSong.isPresent()) {
            Song song = oSong.get();
            play(song);
        } else {
            System.out.println("No songs to play.");
        }
    }

    private void play(Song song) {
        // play the song
    }
}
  • Call the method, get back an Optional instead of the raw object.
  • Check isPresent() (or the inverse, isEmpty()) before using it.
  • get() pulls the value out once you know it's present.

Summary

Creating: Optional.empty(), Optional.of(object). Using: optional.isEmpty(), optional.isPresent(), optional.get(), optional.orElse(object).

Where to use Optionals

Only where a method is genuinely sometimes unable to return something. Don't use them for:

  • method parameters (except in test classes)
  • fields in data classes

Why not null?

Optional was introduced in Java 8. Before that, null was the only way to represent "nothing" — and since null could show up almost anywhere (any method, any variable, any field), a method's signature alone never told you whether it might return null. This led to defensive "null paranoia" — checking every result for null, even when it could never actually happen. Optional fixes this by making the "might be nothing" case explicit and visible in the method signature itself, so the compiler/API nudges you to handle it instead of relying on memory or documentation.