Magnus' blog


Serializable Optional

The default Java Optional is only meant to be used as a return type and is not serializable by default. When you use it for fields or as argument types, it will give a warning. This has not stopped me in the past, because I think it is a brilliant way to express the intent of the developer when describing your code. The serializable limitation can also hit hard, as it will disallow you from caching any object that contains an Optional. I set out to reimplement Optional in a way that is both Serializable and, hopefully, provides some extra benefits.

In the JDK implementation, Optional is implemented as a final class that contains a single value field. For Optional.empty, this value is null. Additionally, a single empty instance is reused across all empty calls.

Instead, I implemented it as a sealed interface with two records for Present and Empty. I then reimplemented the API from Optional, which is quite straightforward as the methods are usually quite self-explanatory. Additionally, I added test cases based on the interface in order to test all possible code paths.

The implementation is available on: https://github.com/HHMagnus/Java-Serializable-Optional

Because of this implementation, you can call all the standard Optional methods, but it also adds new possibilities.

A switch can be used to extract the value:

final var message = switch (optional) {
    case Empty -> "No message";
    case Present(var message) -> message;
};

Additionally, for a normal Optional you would have to do something like this to guard against null:

if (optional.isEmpty()) {
    return;
}
final var message = optional.get();

System.out.println(message);

But with this implementation you could deconstruct the value with:

if (!(optional instanceof Present(var message))) {
    return;
}
System.out.println(message);

This is all in addition to it being Serializable, and I also encourage you to use it as a field or argument.

Performance analysis coming soon.

View next or previous post: