在地图中使用Optional

Jho*_*007 6 java optional

好的,在我开始解释我的问题之前,我想让你知道我知道背后的设计理念Optional,它不打算用于字段或集合,但我已经在Kotlin编程了很多,并且真的不喜欢使用null.

所以我在虚幻引擎中有一个基于节点的编辑器,每个节点都有ConnectionBoxes,它可以是空闲的,也可以被a占用Connection.

因此,有不同的方式来表达这其中之一是利用一张地图,每一个映射ConnectionBox到一个Connection这样的:

Map<ConnectionBox, Connection> connectionEndPoints;
Run Code Online (Sandbox Code Playgroud)

Connection可能是null,如果ConnectionBox是免费的.我不喜欢这个,因为其他开发人员不知道这个Map的功能,并且它可能会返回null现有的ConnectionBox.

所以我很想用一个:

Map<ConnectionBox, Optional<Connection>> connectionEndPoints;
Run Code Online (Sandbox Code Playgroud)

它显示出更好的打算,你甚至可以读出它:
"这ConnectionBox可能有Connection附加的."

我的问题是:为什么我不应该这样做,即使它更明确地表明意图并阻止NPEs.每个SO帖子和每个博客文章都说这是糟糕的风格,甚至编译器也说我不应该发出警告.


根据要求,这里是一个SO线程,不鼓励使用Optional作为字段或集合值:用于可选

这是警告(因为事实证明它是来自IntelliJ的警告):
警告:可选用作字段{fieldName}的类型


好之后,建议Connection引用应该在ConnectioBox问题的范围内转移.

为什么是:

class ConnectionBox {
    Optional<Connection> connection;
    ...
Run Code Online (Sandbox Code Playgroud)

比...更差

class ConnectionBox {
    Connection connection; //may be null
    ...
Run Code Online (Sandbox Code Playgroud)

除非我发表评论,否则您无法看到您可能会遇到NPE并且我不喜欢解释可以解释自己的代码的评论.

bea*_*u13 1

编辑

\n\n

在观看了 Stuart Marks(在 Oracle JDK 小组的核心库团队工作)在 Devoxx 2016 上演讲“Optional \xe2\x80\x93 The Mother of All Bikesheds”之后,您应该跳到54:04

\n\n
\n

为什么不在字段中使用可选?

\n\n
    \n
  • 更多的是风格问题而不是正确性问题\n \n
      \n
    • 通常有更好的方法来模拟值的缺失
    • \n
    • 在字段中使用Optional通常是出于消除可为空字段的盲目愿望
    • \n
    • 请记住,消除空值不是可选的目标
    • \n
  • \n
  • 在字段中使用可选...\n \n
      \n
    • 为每个字段创建另一个对象
    • \n
    • 在每个字段读取时引入内存的相关负载
    • \n
    • 让你的代码变得混乱
    • \n
    • 有什么好处?能够链接方法吗?
    • \n
  • \n
\n
\n\n

原帖

\n\n

根据 IntelliJ 的检查器(首选项 > 编辑器 > 检查 > 用作字段或参数类型的“可选”):

\n\n
\n

可选的设计目的是为库方法返回类型提供有限的机制,其中需要有一种明确的方式来表示“无结果”。java.util.Optional如果类需要为,则使用具有类型的字段也会出现问题Serializable,但事实java.util.Optional并非如此。

\n
\n\n

这也适用于集合,以防您必须序列化它们。此外,请查看这些链接:

\n\n
    \n
  • Java 8 可选:有什么意义?

    \n\n
    \n

    回顾一下 - 为了摆脱 NullPointerExceptions,我们有一个新类:
    \n

    \n\n
      \n
    • 抛出空指针异常
    • \n
    • 本身可以为 null,从而导致 NullPointerException
    • \n
    • 增加堆大小
    • \n
    • 使调试变得更加困难
    • \n
    • 使序列化对象(例如外部客户端的 XML 或 JSON)变得更加困难
    • \n
    \n
  • \n
  • 为什么 java.util.Optional 被破坏了

    \n\n
    \n

    最后一个讽刺的是,通过试图阻止 null,该类的作者实际上鼓励了它的使用。我确信有些人会试图简单地从函数中返回 null,以便“避免创建不必要且昂贵的可选引用”,而不是使用正确的类型和组合器。

    \n
  • \n
\n\n

如果您关心可读性,您还可以使用@Nullable(在EclipseIntelliJ中可用):

\n\n
class ConnectionBox {\n    @Nullable\n    Connection connection;\n    // ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者,您可以创建一个可选的 getter:

\n\n
class ConnectionBox {\n    Connection connection;\n    // ...\n    Optional<Connection> getConnection() {\n        return Optional.ofNullable(connection);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n