java - 为什么 Java 8 Optional 实现为 final,没有 Some 和 None 层次结构?

标签 java java-8 option-type

在 Java 中,Optional实现为 public final class Optional<T> { ... }而不是作为 Some 的密封层次结构和 None .

为什么这里不是这种情况?这是缺少 sealed 的解决方法吗?在 java ?是否有更深层次的原因?

如果你看一下方法实现,你会发现通过这种方式,它具有丑陋的空检查功能:

public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Optional.ofNullable(mapper.apply(value));
    }
}

它们不仅丑陋,而且如果你有更长的方法链,isPresent将需要在每次调用期间进行评估,即使 Optional从一开始就是空的。

如果我们可以将固定的实现传递到链下,就可以避免这种情况。

optional
  .map(i -> i) // isPresent()
  .map(Object::toString) // isPresent()
  .map(String::length) // isPresent()
  .map(...) // isPresent()

问题

为什么不使用子类型为空和非空情况建模?


我没有特别问为什么 Optional是最终的,而不是为什么它没有用 Some 实现和 None ,与许多其他语言一样,所以 Why is optional declared as a final class并不是很有帮助。

最佳答案

总结

class Optional 上的 final 修饰符是为更大的功能做准备:value typesProject Valhalla 的目标(Java 10+ 的功能)。

您可以在下面链接的 2014 年文章中阅读有关 Java 值类型的所有内容:

Value Types for Java


JEP 169起草了在 Java 中实现值对象的提案。

Provide JVM infrastructure for working with immutable and reference-free objects, in support of efficient by-value computation with non-primitive types.

JEP 390暗示“将某些类迁移为原始类”的可能性:

The design and implementation of primitive classes is sufficiently mature that we can confidently anticipate migrating certain classes of the Java Platform to become primitive classes in a future release.


那么这与Optional有什么关系呢?

在 2014 年的论文中,提到了基于值的类如何充当值类型的盒装版本:

In fact, it seems likely that the boxed form of every value type will be a value-based class.

可选value-based class .


为什么我们需要 Java 中的值类型?

在 Java 中,从引用类型实例化的对象有一个 identity .这允许特定对象被变量引用通过引用进行比较。当前所有类/枚举/接口(interface)都创建引用类型。因此,所有对象都有一个身份

但是,理论上,并非所有对象都需要身份,正如上面链接的 2014 年论文中明确提到的:

Object identity serves only to support mutability, where an object’s state can be mutated but remains the same intrinsic object.

身份不是免费的,不可变类型不需要突变,这在继承上意味着它们不需要身份。

不可变类型的标识会导致过多的内存占用:

Object identity has footprint and performance costs, which is a major reason Java, unlike other many object oriented languages, has primitives.

实现值类型

James Gosling 写了一个 article back in 1999关于将不可变类型编译为值:

It is almost possible, under the current language spec, for a sufficiently clever optimizing compiler to transform certain classes into lightweight objects that are not heap allocated and are passed by value rather than reference: declare the class and all its instance variables to be final.

这个想法被 Oracle 的实验性项目 Valhalla 继承,由 Brian Goetz 领导.在准备中,specification for value-based classes已创建,其中一个要求是该类是 final

2014 年关于 Java 值类型的论文进一步揭示了执行最终要求的决定:

Can values participate in inheritance-based subtyping? No.

Can a value class be abstract or non-final? No.


The decision to limit or prohibit subclassing and subtyping of value types is necessary to avoid pointer polymorphism.

We can therefore ensure that all methods are resolved unambiguously in the exact type of the method receiver. Invoking a value method is always like invokestatic or invokespecial and never like invokevirtual or invokeinterface.

值类型不能参与传统的子类型化(如果有的话,也是有限的)。

关于java - 为什么 Java 8 Optional 实现为 final,没有 Some 和 None 层次结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45520538/

相关文章:

java - 了解Options.orElse

ios - SWIFT:var someVariable:int = textfield.text.toInt() x textfield2.text.toInt() 并强制展开

swift - NSURLSession/NSURLConnection HTTP 加载失败(kCFStreamErrorDomainSSL,-9843) fatal error : unexpectedly found nil while unwrapping an Optional value

java - 我如何知道何时更新数据库 - Android

java - Stream#limit 可以返回比预期更少的元素吗?

java - Java8是否支持运算符重载

java - 不同对象类型java 8的两个集合的交集

java - 如何从 Activemq 异步拉取消息

java - 导出的 JAR 没有创建它应该创建的文件

java - 保存多个文件而不替换现有文件