Java 8 Elvis运算符中的空检查?

时间:2014-10-23 13:21:22

标签: java nullpointerexception java-8

问题:是否有针对任何未来Java版本安排的 Elvis运算符的实现?或者是否有任何库将它带到Java?

我已经读过那个

  

它是针对Java SE 7提出的,但没有进入该版本

http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html

我知道Java 8允许这个

String name = computer.flatMap(Computer::getSoundcard)
                          .flatMap(Soundcard::getUSB)
                          .map(USB::getVersion)
                          .orElse("UNKNOWN");

但是我的口味太过分了。因此,如果有人能指出任何将Groovy喜欢/ C#类似语法的项目/库用于Null Checks的Java,我将不胜感激。

编辑:通过Elvis运营商,我的意思是:

String version = computer?.getSoundcard()?.getUSB()?.getVersion();

或类似的

2 个答案:

答案 0 :(得分:13)

没有。目前或将来没有计划重新考虑Java中的零安全运算符。

答案 1 :(得分:0)

很久以前就有一个函数

public static Foo getFoo(Bar bar) {
  return bar.getFoo();
}

人们无法同意如果 bar 为 null 会发生什么。

首先,有人会声称违反函数的意图应该受到受检异常的惩罚。

public static Foo getFoo(Bar bar) throws FooNotFoundException {
  if (bar == null) throw new FooNotFoundException();
  return bar.getFoo();
}

函数的调用者将被迫考虑这种情况。它必须捕获异常或重新抛出它。它会如此强大以至于会惹恼人们,很快他们就会争辩说这不应该是已检查的异常,而是运行时异常,以使其不那么强大。

public static Foo getFoo(Bar bar) {
  if (bar == null) throw new FooNotFoundException();
  return bar.getFoo();
}

有些人会声称抛出异常没有意义,因为无论如何 java 都会抛出异常:空指针异常

那些害怕出现意外异常的人只会让他们的代码更加鲁棒,并会在他们的函数开头添加 null-检查,这会简单地返回 null .

public static Foo getFoo(Bar bar) {
  if (bar == null) return null;
  return bar.getFoo();
}

很快人们就会争论是否可以返回空列表,或者这些空列表是否实际上也应该是 null 值。 “当然,您不想在每次迭代之前检查可空性,对吗?”对方会不会争论。很快,他们就会创建各种结构来完全避免可空性

public static Foo getFoo(Bar bar) {
  if (bar == null) return Foo.Empty;
  return bar.getFoo();
}

每种方法都会产生广泛的后果。而这些后果将使不同方法难以结合。这些后果将导致编码规则,其中每个单独的规则都将与下一个规则纠缠在一起。这种纠缠给人的印象是每一条规则都是无可争议的。最后,编码规则将变得像宗教一样,只有在完整规则集的范围内才有意义。

根据您选择的规则集,您在使用某些框架时会遇到困难。 最终,带有未检查例外的空列表宗教成为主导。这种宗教可以总结如下:

  • 您应该避免返回 null 值。
  • 如果列表为空,则按原样返回。
  • 如果你迭代一个列表,你永远不必检查 null。
  • 方法不应该抛出已检查的异常
  • 受检异常应包含在运行时异常中。
  • 字符串不应该是 null,而应该是 ""

显然这种宗教变得如此强大,以至于它成功地影响了框架和语言规范

  • 针对空列表的编译器优化
  • Optional
  • 值类型

一些外部库和编辑器实际上会尝试通过提供注释(@Null@NotNull)来重新团结不同的团队。 IDE 只会为您标记所有违规行为。一个简单但有效的解决方案。尽管如此,JDK 从未包含自己的 @Null@NotNull,而是每个库都必须发布自己的。

考虑到所有这些,现在,Java 中不太可能有 elvis 运算符。如果你想用 java 编码,你最好忘记 null

或者用 Tony Hoare(null 的发明者)的话来说:

<块引用>

我称之为我的十亿美元错误。这是零的发明 1965年参考。当时我在设计第一个 面向对象中引用的综合类型系统 语言 (ALGOL W)。我的目标是确保所有引用的使用 应该是绝对安全的,检查自动执行 编译器。但我无法抗拒放入空值的诱惑 参考,只是因为它很容易实现。这导致 无数的错误、漏洞和系统崩溃, 在过去的四十年中可能造成了十亿美元的痛苦和伤害 年。

就个人而言,我认为这绝对没有意义,因为每个体面的编程语言都有一个空值。有些甚至有多个表示不同类型的可空性。毕竟,即使在数学中也有未定义的值

无论如何,如果你没有猫王接线员,你仍然可以

Foo foo = bar == null ? null : bar.getFoo();

这完全符合 java 的精神。毕竟,在 2021 年,java 是一种非常显式的语言。