【问题标题】:Optional for nullable types?可空类型的可选?
【发布时间】:2020-01-23 15:09:03
【问题描述】:

是否有可能以某种方式将可为空的类型传递给 Optional? 示例:

class X(
    val x: Optional<Int?>
)

为什么?

我想通过以下方式序列化:

X(Optional.of(1)) -> {"x":1}
X(Optional.of(null)) -> {"x":null} // <- throws
X(Optional.empty()) -> {}

通知

我发现使用 double Optional 可以做我想做的事,像这样:

class X(
    val x: Optional<Optional<String>>
)

但如果 Kotlin 可空类型有办法或知道为什么没有办法,那还是很有趣的。

【问题讨论】:

  • Optional.ofNullable
  • Optional.of(null) 会抛出 NPE
  • Optional&lt;Int&gt;? 应该这样做。即使我建议定义一些临时类来表达这种行为。

标签: java kotlin jackson optional nullable


【解决方案1】:

不建议使用val x: Optional&lt;Int?&gt;,因为根据定义,您无法创建带有null 值的Optional 容器,并且如果您尝试使用Optional.of(null) 创建Optional,则会遇到NPE。 Optional.of(value) 接受一个不可为空的值 (doc),Optional.ofNullable(value) 可以接受一个可为空的值,但会返回一个空的 Optional (doc)。

如果您希望能够通过以下方式进行序列化

X(Optional.of(1)) -> {"x":{"present":true}}
X(null) -> {"x":null}

你可以定义如下的类

class X(
    val x: Optional<Int>?
)

棘手的部分是能够如下序列化

X(Optional.empty()) -> {}

因为默认情况下,Jackson 会将其序列化为{"x":{"present":false}}。您必须避免的唯一选择是在ObjectMapper 中注册Jdk8Module (source) 和jackson-datatype-jdk8 依赖项

val mapper = ObjectMapper()
val jdk8Module = Jdk8Module()
jdk8Module.configureAbsentsAsNulls(true)
mapper.registerModule(jdk8Module)

但这会将空的 Optional 视为 Java null 从而序列化如下

X(Optional.empty()) -> {"x":null}
X(Optional.of(1)) -> {"x":1}

Optional.ofNullable(value)nullvalue 的行为类似于 Optional.empty(),因为两者都会返回一个空的 Optional

获得X(Optional.empty()) -&gt; {} 的唯一方法是使用@JsonInclude(JsonInclude.Include.NON_NULL) 注释字段,但这也意味着您将获得序列化X(null) -&gt; {}

【讨论】:

    猜你喜欢
    • 2010-10-21
    • 1970-01-01
    • 2014-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-25
    相关资源
    最近更新 更多