Reputation: 24534
Is it possible to somehow pass nullable types to Optional? Example:
class X(
val x: Optional<Int?>
)
I want to serialize this the following way:
X(Optional.of(1)) -> {"x":1}
X(Optional.of(null)) -> {"x":null} // <- throws
X(Optional.empty()) -> {}
I've found out that it's possible to do what I want with double Optional, like this:
class X(
val x: Optional<Optional<String>>
)
But it'd still be interesting if there's a way with Kotlins nullable types or to know why there's not.
Upvotes: 3
Views: 1232
Reputation: 15183
Having val x: Optional<Int?>
is not advised, as you cannot create an Optional container with a null
value in it by its definition, and you would encounter a NPE if you try to create an Optional with Optional.of(null)
. Optional.of(value)
takes in a non-nullable value (doc) and Optional.ofNullable(value)
can take in a nullable value, but would return an empty Optional
(doc).
If you want to be able to serialize the below way
X(Optional.of(1)) -> {"x":{"present":true}}
X(null) -> {"x":null}
you may define the class as below
class X(
val x: Optional<Int>?
)
The tricky part is to be able to serialize as below
X(Optional.empty()) -> {}
Since by default, Jackson will serialize it as {"x":{"present":false}}
. The only option that you have to avoid that is to register Jdk8Module
(source) with jackson-datatype-jdk8
dependency in ObjectMapper
by
val mapper = ObjectMapper()
val jdk8Module = Jdk8Module()
jdk8Module.configureAbsentsAsNulls(true)
mapper.registerModule(jdk8Module)
But this would treat an empty Optional as Java null thereby serializing as below
X(Optional.empty()) -> {"x":null}
X(Optional.of(1)) -> {"x":1}
Optional.ofNullable(value)
with null
as value
would behave similar to Optional.empty()
as both would return an empty Optional
.
The only way to get X(Optional.empty()) -> {}
would be by annotating the field with @JsonInclude(JsonInclude.Include.NON_NULL)
, but that would also mean that you'd get the serialization X(null) -> {}
Upvotes: 1