20

我有点等待这个问题的“不”回答。

如果您在 if 子句中检查变量时是否可以同时保存变量,我很感兴趣。

假设我有这个代码。

if(foo!=null){
  if(foo.getBar()!=null){
    Bar bar = foo.getBar();
    System.out.println("Success: " + bar);
  } else {
    System.out.println("Failure.");
  }
} else {
  System.out.println("Failure.");
}

我现在独立处理“失败”状态,即使结果相同。我可以像这样把它们放在一起:

if(foo!=null && foo.getBar()!=null){
  Bar bar = foo.getBar();
  System.out.println("Success: " + bar);
} else {
  System.out.println("Failure.");
} 

已经更整洁的代码了。如果 foo 为空,它将停在那里并且不会尝试 foo.getBar(在 if 中),所以我不会得到 NPE。我想增强的最后一件事,也是主要问题:我真的两次调用 foo.getBar() 吗?如果 getBar() 是一个非常繁重的操作,那么摆脱第二个相同的调用会很好。所以我想知道是否有可能做一些与此类似的事情:

if(foo!=null && (Bar bar = foo.getBar())!=null){
  Bar bar = foo.getBar();
  System.out.println("Success: " + bar);
} else {
  System.out.println("Failure.");
}

如果我愿意的话,我必须把它分成两个不同的 if's again

Bar bar = foo.getBar();
if (bar!=null) ...
4

7 回答 7

35

这是你能得到的最接近的:

Bar bar;
if(foo!=null && (bar = foo.getBar())!=null){
  System.out.println("Success: " + bar);
} else {
  System.out.println("Failiure.");
}
于 2009-02-19T07:53:21.017 回答
13

我在从 BufferedReader 遍历行时使用了该技术:

BufferedReader br = // create reader
String line
while ((line = br.readLine()) != null) {
    // process the line
}

所以是的,你可以做一个赋值,结果就是左边的变量,然后你可以检查它。但是,在测试中声明变量是不合法的,因为它们只会被限定为该表达式。

于 2009-02-19T07:52:01.177 回答
7

如果您想限制 Bar bar 的范围,我会在 Michael 发布的代码周围添加 { 和 }。

无效的富()
{
    // 一些代码...

    // 这个块限制了“Bar bar”的范围,使得该方法的其余部分看不到
    // 它。
    {
        酒吧酒吧;
        if(foo!=null && (bar = foo.getBar())!=null){
            System.out.println("成功:" + bar);
        } 别的 {
            System.out.println("失败。");
        }
    }
}

如果有意义,您可能还想检查空对象模式。如果可以的话,我个人会尽量避免事情为空……真的要考虑是否要允许空值。

于 2009-02-19T08:07:50.700 回答
2

来自“我的编程语言比你的编程语言更好”部门:在Groovy中,您可以使用“?”。操作员:

Bar bar = foo?.bar
if (bar != null) {
}

在 Java 中,这是一个很好的模式(*):

Bar bar = foo == null ? null : foo.getBar();
if (bar != null) {
}

*:您可以保存在指尖的东西。

于 2009-02-19T10:34:25.077 回答
1

完全无法回答问题的三点:

null是邪恶的。不要编写返回它的方法。然后,您的示例问题将消失。

我认为您可能会错过封装。而不是可以使您执行“告诉不要问”操作foo.getBar()的界面?foo

表达式中的副作用往往会导致错误的代码。喜欢更多、更简单的线条而不是更少、错误的线条。++如果在访问缓冲区或类似的迭代器样式算法时使用增加索引,则通常的例外情况。

于 2009-02-19T13:06:08.317 回答
0

实际上我认为这是一种使用 Java Optional 的方法,这里有一个例子:

Optional.ofNullable("text").ifPresent( $0 -> {
  System.out.println($0.toUpperCase());
});

或者在你的情况下:

  if(foo != null){
      Optional.ofNullable(foo.getBar()).ifPresent(bar -> {
          System.out.println("Success: " + bar);
      });
  }
于 2018-03-22T14:02:27.233 回答
0

您不能在 Java 条件中声明变量,但可以在for循环中:

for (Bar bar = (null != foo) ? foo.getBar() : null; bar != null;) {
    System.out.println("Success: " + bar);
    break;
}

但这并不漂亮。我完全同意汤姆霍廷的评论。

于 2021-07-21T22:59:00.780 回答