在地图中使用Optional

时间:2016-10-21 12:03:00

标签: java optional

好的,在我开始解释我的问题之前,我想让你知道我知道null背后的设计理念,并且不打算在字段或集合中使用,但我编写了很多Kotlin目前非常不喜欢使用ConnectionBox

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

因此,有不同的方法可以表达这一点,即使用将每个Connection映射到Map<ConnectionBox, Connection> connectionEndPoints; 的地图,例如:

Connection
如果null是免费的,则

ConnectionBox可以是null。我不喜欢这样,因为其他开发人员不知道此Map的功能,并且它可能会返回现有ConnectionBox的{​​{1}}。

所以我很想使用:

Map<ConnectionBox, Optional<Connection>> connectionEndPoints;

显示更好的打算,你甚至可以读出它:
“此ConnectionBox可能附加了Connection。”

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

根据要求,这里有一个SO线程,不鼓励使用Optional作为字段或集合值:Uses for Optional

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

好的,建议Connection引用应该在ConnectioBox内,问题只是转移。

为什么:

class ConnectionBox {
    Optional<Connection> connection;
    ...

更糟糕
class ConnectionBox {
    Connection connection; //may be null
    ...

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

1 个答案:

答案 0 :(得分:2)

修改

在观看了Stuart Marks(他在Oracle的JDK小组的核心图书馆团队工作)与Devoxx 2016讨论"Optional – The Mother of All Bikesheds"之后,你应该跳到54:04

  

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

     
      
  • 更多的是样式问题,而不是正确性问题      
        
    • 通常有更好的方法来模拟缺席值
    •   
    • 在字段中使用Optional通常源于消除可空字段的盲目愿望
    •   
    • 请记住,消除空值不是Optional
    • 的目标   
  •   
  • 在字段中使用可选...      
        
    • 为每个字段创建另一个对象
    •   
    • 在每个字段读取
    • 时从内存中引入依赖负载   
    • 使您的代码混乱
    •   
    • 有什么好处?链方法的能力?
    •   
  •   

原帖

根据IntelliJ的检查员(首选项&gt;编辑器&gt;检查&gt;'可选'用作字段或参数类型):

  

可选项旨在为库方法返回类型提供有限的机制,其中需要一种明确的方式来表示“无结果”。如果类需要java.util.Optional,而Serializable不是java.util.Optional,则使用类型为@Nullable的字段也会出现问题。

如果您必须serialize,这也适用于集合。此外,看看这些链接:

  • Java 8 Optional: What's the Point?

      

    所以回顾一下 - 为了摆脱NullPointerExceptions,我们有一个新的类:   

         
        
    • 抛出NullPointerExceptions
    •   
    • 本身可以为null,导致NullPointerException
    •   
    • 增加堆大小
    •   
    • 使调试更加困难
    •   
    • 使序列化对象(比如外部客户端的XML或JSON)更加困难
    •   
  • Why java.util.Optional is broken

      

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

如果您关心可读性,还可以使用class ConnectionBox { @Nullable Connection connection; // ... } Eclipse以及IntelliJ中提供):

class ConnectionBox {
    Connection connection;
    // ...
    Optional<Connection> getConnection() {
        return Optional.ofNullable(connection);
    }
}

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

static void Main(string[] args)
        {
            bool bMethod1 = Metthod1();
            bool bMethod2 = Metthod2();
            bool bMethod3 = Metthod3();

            if (!bMethod1 || !bMethod2 || !bMethod3)
            {
                //RollBack 
            }
        }