T
- the type of the wrapped valuepublic final class SerializableOptional<T extends Serializable> extends Object implements Serializable
Optional
for serialization. Instances of this class are immutable.
Note that it does not provide any of the methods Optional
has as its only goal is to enable serialization.
But it holds a reference to the Optional
which was used to create it (can be accessed with
asOptional()
). This Optional
instance is of course reconstructed on deserialization, so it will not
be the same as the one specified for its creation.
The class can be used as an argument or return type for serialization-based RPC technologies like RMI.
There are three ways to use this class to serialize instances which have an optional field.
The field can be declared as transient Optional<T> optionalField
, which will exclude it from serialization.
The class then needs to implement custom (de)serialization methods writeObject
and readObject
. They
must transform the optionalField
to a SerializableOptional
when writing the object and after reading
such an instance transform it back to an Optional
.
private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject( SerializableOptional.fromOptional(optionalField)); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); optionalField = ((SerializableOptional<T>) in.readObject()).toOptional(); }
If the class is serialized using the Serialization Proxy Pattern (see Effective Java, 2nd Edition by Joshua
Bloch, Item 78), the proxy can have an instance of SerializableOptional
to clearly denote the field as being
optional.
In this case, the proxy needs to transform the Optional
to SerializableOptional
in its constructor
(using fromOptional(Optional)
) and the other way in readResolve()
(with
asOptional()
).
The field can be declared as SerializableOptional<T> optionalField
. This will include it in the
(de)serialization process so it does not need to be customized.
But methods interacting with the field need to get an Optional
instead. This can easily be done by writing
the accessor methods such that they transform the field on each access.
Note that asOptional()
simply returns the Optional
which with this instance was created so no
constructor needs to be invoked.
Note that it is rarely useful to expose an optional field via accessor methods. Hence the following are private and for use inside the class.
private Optional<T> getOptionalField() { return optionalField.asOptional(); } private void setOptionalField(Optional<T> optionalField) { this.optionalField = SerializableOptional.fromOptional(optionalField); }
Modifier and Type | Method and Description |
---|---|
Optional<T> |
asOptional()
Returns the
Optional instance with which this instance was created. |
static <T extends Serializable> |
empty()
Creates a serializable optional which wraps an empty optional.
|
static <T extends Serializable> |
fromOptional(Optional<T> optional)
Creates a serializable optional from the specified optional.
|
static <T extends Serializable> |
of(T value)
Creates a serializable optional for the specified value by wrapping it in an
Optional . |
static <T extends Serializable> |
ofNullable(T value)
Creates a serializable optional for the specified value by wrapping it in an
Optional . |
public static <T extends Serializable> SerializableOptional<T> fromOptional(Optional<T> optional)
T
- the type of the wrapped valueoptional
- the Optional
from which the serializable wrapper will be createdSerializableOptional
which wraps the specified optionalpublic static <T extends Serializable> SerializableOptional<T> empty()
T
- the type of the non-existent valueSerializableOptional
which wraps an empty
Optional
Optional.of(Object)
public static <T extends Serializable> SerializableOptional<T> of(T value) throws NullPointerException
Optional
.T
- the type of the wrapped valuevalue
- the value which will be contained in the wrapped Optional
; must be non-nullSerializableOptional
which wraps the an optional for the specified valueNullPointerException
- if value
is nullOptional.of(Object)
public static <T extends Serializable> SerializableOptional<T> ofNullable(T value)
Optional
.T
- the type of the wrapped valuevalue
- the value which will be contained in the wrapped Optional
; may be nullSerializableOptional
which wraps the an optional for the specified valueOptional.ofNullable(Object)
This documentation is licensed under CC-BY 4.0, attributed to Nicolai Parlog from CodeFX.