【问题标题】:Why does Guava's Optional use abstract classes when Java 8's uses nulls?当 Java 8 使用空值时,为什么 Guava 的 Optional 使用抽象类?
【发布时间】:2014-04-11 03:33:36
【问题描述】:

当 Java 8 发布时,我期待它的 Optional 实现与 Guava 的实现基本相同。从用户的角度来看,它们几乎是相同的。但是 Java 8 的 Optional 在内部使用 null 来标记一个空的 Optional,而不是使 Optional 抽象并有两个实现。除了 Java 8 的版本感觉错误(您只是通过隐藏您确实仍在使用它们的事实来避免空值)之外,每次您想要访问它时检查您的引用是否为空不是效率较低,而是而不仅仅是调用一个抽象方法?也许不是,但我想知道他们为什么选择这种方法。

【问题讨论】:

  • 我不认为会有太大的性能差异——决定调用哪个方法的运行时成本可能与空检查的成本大致相同。
  • 我不明白“感觉不对”的事情。 OOP(尤其是)都是关于隐藏实现的,对吧?如果这些方法通过执行我期望它们执行的操作来满足合同,我不应该担心实现这一目标的幕后操作。
  • 我只知道这两个实现的创建者都是一些非常聪明的人,所以我想知道为什么没有达成共识。

标签: java null guava java-8


【解决方案1】:

也许 Google Guava 的开发者想要开发一种更接近于函数式世界的习语:

datatype ‘a option = NONE | SOME of ‘a

在这种情况下,您使用模式匹配来检查类型选项实例的真实性质。

case x of
    NONE => //address null here
  | SOME y => //do something with y here

通过将 Option 声明为抽象类,Google Guava 遵循这种方法,其中 Option 表示类型 ('a option),ofabsent 的子类将表示此的特定实例类型(SOME 'aNONE)。

Option 的设计是thoroughly discussed in the lambda mailing list。用 Brian Goetz 的话来说:

问题在于期望。这是经典的“盲人” 和大象”的问题;叫做 Optional 的东西有不同 不同观点的“本质”,问题不在于 每个都无效,问题是我们都使用相同的 描述不同概念的词(更准确地说,假设 JDK 团队的目标与您的人的目标相同 居高临下地称其为“熟悉概念的人”。

Optional 的设计范围很窄 JDK。目前的设计大多满足这一点;它可能会延长 以小方式,但目标不是创建选项单子或解决 monad 选项旨在解决的问题。 (即使我们 这样做了,结果仍然可能不令人满意;没有 类库的其余部分遵循相同的 monadic API 约定, 没有更高种类的泛型来抽象不同种类的 monads,没有对

从纯粹的实用角度来看,围绕 Optional 的讨论有 超出其设计预算几个数量级。我们已经 仔细考虑了我们收到的大量投入,没有花费 思考了一小段时间,得出的结论是 当前的设计中心是适合当前时间的设计中心。什么是 当然意味着善意的输入实际上正在迅速变成 拒绝服务攻击。我们可以花无数时间争论这个 来回走,结果就不会有 JDK 8。我确定没有人 想要那个。

所以,让我们对主题的意见保持在 当前实现的设计中心,而不是试图 说服我们改变设计中心。

【讨论】:

    【解决方案2】:

    我希望虚拟方法调用查找更昂贵。您必须加载虚函数表,查找偏移量,然后调用该方法。空检查是从寄存器而不是内存中读取的单个字节码。

    【讨论】:

    • 忘记字节码。解释代码的性能几乎无关紧要,而且 JIT 所做的看起来完全不同。
    • true,不过它应该归结为 1 条比较指令。虚拟方法的查找、调用和执行仍然会产生更大的影响。
    猜你喜欢
    • 1970-01-01
    • 2012-03-22
    • 1970-01-01
    • 1970-01-01
    • 2015-11-02
    • 1970-01-01
    相关资源
    最近更新 更多