The root of this library is the Option<T>
interface which is subclassed by the
interfaces NullableOption<T>
and NonNullOption<T>
.
Option
is the base interface for the library and includes most if not all the
features of the built-in Optional
type.
NonNullOption
extends the Option
interface and is a more of a direct mirror
of the built-in Optional
. Implementations of this interface do not allow
wrapping null
and translate null
to "empty".
The primary entry point for this library is the included Opt
factory which is
used to construct the different Option
types. This factory includes a
standard configuration, but may be overridden with an alternate implementation.
NullableOption
// Empty nullable option
var opt1 = Opt.nullable();
// Nullable option wrapping null
var opt2 = Opt.nullable(null);
// Nullable option wrapping a non-null value
var opt3 = Opt.nullable("hello");
NonNullOption
// Empty option
var opt1 = Opt.nonNull();
// Empty option
var opt2 = Opt.nonNullOfNullable(null);
// Non-empty option
var opt3 = Opt.nonNull(1234);
// Non-empty option
var opt4 = Opt.nonNullOfNullable("goodbye");
// Throws NullPointerException
var opt5 = Opt.nonNull(null);
<dependency>
<groupId>io.foxcapades.lib</groupId>
<artifactId>opt</artifactId>
<version>1.1.0</version>
</dependency>
implementation 'io.foxcapades.lib:opt:1.1.0'
implementation("io.foxcapades.lib:opt:1.1.0")
Using custom implementations of option types may be used with the option factory
Opt
by extending the Opt
class and setting it as the default/singleton
instance.
public class MyOpt extends Opt {
@Override
public <T> NullableOption<T> newNullable() {
return new MyOption<>();
}
}
...
Opt.setStandardInstance(new MyOpt());
assert Opt.nullable() instanceof MyOpt;
In practice, especially when dealing with external APIs, I have personally found
myself frustrated with the Optional
type’s lack of features, inability to wrap
null
, and the fact that the type is final
so desired features could not even
be added.