Java"?" 检查null的运算符 - 它是什么?(不是三元!)

Ert*_*ohl 69 java syntax null

我正在阅读一篇关于斜线故事的文章,并发现了这个小小的问题:

采用最新版本的Java,它试图通过为无限指针测试提供简写语法来简化空指针检查.只需在每个方法调用中添加一个问号,就会自动包含对空指针的测试,替换大鼠的if-then语句嵌套,例如:

    public String getPostcode(Person person) {
      String ans= null;
      if (person != null) {
        Name nm= person.getName();
        if (nm!= null) {
          ans= nm.getPostcode();
        }
      }
      return ans
    } 

public String getFirstName(Person person) {
      return person?.getName()?.getGivenName();
    } 

我已经浏览了互联网(好吧,我花了至少15分钟在谷歌问号上搜索变种)并没有得到任何结果.所以,我的问题是:有关于此的官方文件吗?我发现C#有一个类似的运算符("??"运算符),但是我想得到我正在使用的语言的文档.或者,这只是我使用的三元运算符从未见过.

谢谢!

编辑:链接到文章:http://infoworld.com/d/developer-world/12-programming-mistakes-avoid-292

ata*_*lor 69

最初的想法来自groovy.作为Project Coin的一部分,它被提议用于Java 7:https://wiki.openjdk.java.net/display/Coin/2009+Proposals+TOC(Elvis和其他Null-Safe Operators),但尚未被接受.

相关的Elvis算子?:被提议做x ?: y简写x != null ? x : y,当x是一个复杂的表达式时特别有用.

  • `?`是埃尔维斯普雷斯利的标志性的quiff; `:`像往常一样代表一双眼睛.也许`?: - o`更令人回味...... (42认同)
  • @Karl:将它向右转90度,就像一个`:-)`smilie. (14认同)
  • `?:0`应该是"非null,也不是0"运算符.这样做. (4认同)
  • 将提案称为 Elvis 运营商实际上是错误的。http://mail.openjdk.java.net/pipermail/coin-dev/2009-July/002089.html 的解释“空安全解除引用”是一个更好的术语。 (3认同)
  • 在java(其中没有自动强制为null)的简写为`x!= null?x:y` (2认同)

Col*_*inD 53

这种语法在Java中不存在,也不会被包含在我所知道的任何即将发布的版本中.

  • @Webinator:几张海报都评论说提交了提案但被拒绝了.因此答案是100%准确的.提出反对投票的反对意见. (9认同)
  • 为什么选择downvote?据我所知,这个答案100%正确...如果你知道不同的东西,请说出来. (7认同)
  • @Webinator:它不会出现在Java 7或8中,而且目前还没有其他"即将推出的版本".我也发现它不太可能成功,因为它鼓励相当不好的做法.我也不认为"尚未"是必要的,因为"Java中不存在"与"Java中永远不存在"不同. (6认同)
  • @ColinD _bad practice_ 是当你放弃这个丑陋的代码并决定使用 `Optional` 和 `map` 东西时。如果 value 可以为 null,我们并没有隐藏问题,这意味着它有时会为 null,您必须处理它。有时默认值是完全合理的,这不是一个坏习惯。 (3认同)
  • Java 只是拒绝变得有点现代。就终止这种语言吧。 (3认同)
  • 但显然,它已经在某一时刻被提交了(参见 Tom Hawtin 的评论),并且可能会进入该语言。所以“这个语法在 Java 中**还不存在**”* 会更合适。 (2认同)

Pau*_*ams 16

在Java 7中有一个提议,但它被拒绝了:

http://tech.puredanger.com/java7/#null


Hel*_*ira 16

解决缺乏"?"的一种方法 使用Java 8的运算符没有try-catch的开销(它也可以隐藏NullPointerException其他地方,如上所述)是在Java-8-Stream样式中创建一个"管"方法的类.

public class Pipe<T> {
    private T object;

    private Pipe(T t) {
        object = t;
    }

    public static<T> Pipe<T> of(T t) {
        return new Pipe<>(t);
    }

    public <S> Pipe<S> after(Function<? super T, ? extends S> plumber) {
        return new Pipe<>(object == null ? null : plumber.apply(object));
    }

    public T get() {
        return object;
    }

    public T orElse(T other) {
        return object == null ? other : object;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,给定的示例将变为:

public String getFirstName(Person person) {
    return Pipe.of(person).after(Person::getName).after(Name::getGivenName).get();
}
Run Code Online (Sandbox Code Playgroud)

[编辑]

经过进一步思考,我发现只有使用标准的Java 8类才能实现相同的目标:

public String getFirstName(Person person) {
    return Optional.ofNullable(person).map(Person::getName).map(Name::getGivenName).orElse(null);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,甚至可以选择默认值(如"<no first name>"),而不是null将其作为参数传递orElse.

  • 这是过度使用......并且令人沮丧。 (3认同)

Ous*_* D. 9

Java 没有确切的语法,但从 JDK-8 开始,我们有Optional API和各种方法可供我们使用。因此,使用空条件运算符的 C# 版本:

return person?.getName()?.getGivenName(); 
Run Code Online (Sandbox Code Playgroud)

可以使用Optional API用 Java 编写如下:

 return Optional.ofNullable(person)
                .map(e -> e.getName())
                .map(e -> e.getGivenName())
                .orElse(null);
Run Code Online (Sandbox Code Playgroud)

如果person,getName或 中的任何一个getGivenName为 null,则返回 null。

  • 如果此类运算符不可用,则需要一个令人印象深刻的样板代码示例 ~ 41 与 97 个字符。 (9认同)

Dar*_*ron 7

请参阅:https://blogs.oracle.com/darcy/project-coin : -the- final-five-or- so(特别是"Elvis和其他null安全操作符").

结果是Java 7考虑了此功能,但未包括在内.


And*_*yle 6

这实际上是Groovy的安全解除引用运算符.你不能在纯Java中使用它(遗憾的是),因此帖子完全错误(或者更可能有些误导,如果它声称Groovy是"最新版本的Java").

  • 所以这篇文章是错误的 - 原生 java 中不存在语法。唔。 (2认同)