Наличие val x: Optional<Int?>
не рекомендуется, поскольку вы не можете создать дополнительный контейнер с значением null
в его определении, и вы встретите NPE, если попытаетесь создать дополнительный с Optional.of(null)
. Optional.of(value)
принимает необнуляемое значение ( do c), а Optional.ofNullable(value)
может принимать обнуляемое значение, но возвращает пустое Optional
( do c).
Если вы хотите иметь возможность сериализовать следующий способ
X(Optional.of(1)) -> {"x":{"present":true}}
X(null) -> {"x":null}
, вы можете определить класс следующим образом
class X(
val x: Optional<Int>?
)
Сложная часть чтобы иметь возможность сериализации, как показано ниже
X(Optional.empty()) -> {}
Так как по умолчанию Джексон будет сериализовать его как {"x":{"present":false}}
. Единственный вариант, который вы должны избегать, это зарегистрировать Jdk8Module
( source ) с jackson-datatype-jdk8
зависимостью в ObjectMapper
от
val mapper = ObjectMapper()
val jdk8Module = Jdk8Module()
jdk8Module.configureAbsentsAsNulls(true)
mapper.registerModule(jdk8Module)
Но это будет относиться к пустому как Java null, тем самым сериализуя, как показано ниже
X(Optional.empty()) -> {"x":null}
X(Optional.of(1)) -> {"x":1}
Optional.ofNullable(value)
с null
, так как value
будет вести себя подобно Optional.empty()
, так как оба вернут пустой Optional
.
Единственный способ получить X(Optional.empty()) -> {}
- это пометить поле с помощью @JsonInclude(JsonInclude.Include.NON_NULL)
, но это также будет означать, что вы получите сериализацию X(null) -> {}