为什么我们可以在Optional.of()上调用.orElse()



我很好奇为什么可以这样做(至少在Java 8上(:

Optional.of(null).orElse("something");

CCD_ 1基本上是一个有保证的空指针。能够在上面调用.orElse()会给笨拙的开发人员带来意想不到的漏洞。我一直在四处寻找是否有任何理由。也许这应该解决一些场景?

您可以这样做,原因与编写((String) null).length()的原因相同。Java编译器有一个静态检查器来检查某些事情,比如类型安全,但不检查或拒绝可证明抛出NullPointerException的代码。如果是这样,代码throw new NullPointerException();也将不被允许。

通常情况下,引发异常的代码不是错误的。虽然静态检查器可以检测到这种事情并发出警告,但如果这是一个错误,那就太糟糕了。有些IDE会针对可能的错误生成自己的警告,但您必须决定哪些值得检查或不值得检查。

检测这种可能的错误需要一个静态检查器,该检查器是根据Optional.of方法的行为知识设计的。Java语言规范的作者已经决定警告不安全的强制转换之类的事情,但不警告任何取决于所使用方法语义的事情。这个决定的一个优点是,它意味着JLS可以与Java类库文档分开维护。

有些语言支持在编译器中直接进行null检查(甚至更好的语言根本没有这样的"东西"(-这会被烧到编译器中。

javac不是这样的编译器,坦率地说,我也不希望它变成这样。有些语言有!?Optional.of(null)0这样的语法——当我读到这段代码时,它要么对我大喊大叫,要么问我一些问题(这是我的观点(。

现在,回想一下Optional是为返回类型设计的,所以在方法体中使用Optional方法链。如果真的想检查某个东西是否为空,那么就有Objects::requireNonNull——使用它;如果您不确定某个内容是否为null,可以使用Optional::ofNullable

我知道并阅读了Optional::ofOptional::ofNullable的论点,我仍然不喜欢它,我希望它能只是后者。但是,嘿,人们不必总是同意:我们确实有Optional::isEmptyOptional::isPresent。这是个好决定吗?我不知道。

与任何其他方法调用一样,您可以将null传递给任何对象引用,Optional也不例外。他们能为javac添加语义以仅支持Optional::of和null检查吗?可能有多少人会请求对和此功能的支持

Optional.of(null).orElse();

显然,上面的代码总是会导致异常。但是:呢

Optional.of(someMethod()).orElse();

带有

Object someMethod() { return null; }

你可能会想:当然,同样的事情。

事实上这是错误的。如果子类重写someMethod()以返回null以外的值,该怎么办?!因此,您无法在编译时决定该方法是否会在runtime始终返回null。

长话短说:编译器可以应用各种技术(如数据流分析(来确定代码是否会导致运行时异常,这有很多明显的情况,也有不太明显的情况。但也有许多其他地方不可能做到这一点。

这里的重点是:由定义语言的人来决定他们希望编译器关心什么。

java人员选择了简单的编译器。一个编译速度快、实现起来不太复杂的程序。为什么?因为编译器只是为了避免过于复杂的检查。

最新更新