你能在if子句中存储一个变量吗?

Can you store a variable inside a if-clause?

提问人:Jens Jansson 提问时间:2/19/2009 最后编辑:bluishJens Jansson 更新时间:7/22/2021 访问量:10971

问:

我有点在等待这个问题的“否”答案。

我很感兴趣,当你在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 为 null,它将停在那里并且不会尝试 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.");
}

如果我想的话,我必须把它分成两个不同的如果

Bar bar = foo.getBar();
if (bar!=null) ...
Java IF-语句 初始化

评论


答:

14赞 Staale 2/19/2009 #1

我在迭代 BufferedReader 中的行时使用了该技术:

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

所以,是的,你可以做一个赋值,结果将是左侧变量,然后你可以检查它。但是,在测试中声明变量是不合法的,因为它们的范围仅限于该表达式。

37赞 Michael Borgwardt 2/19/2009 #2

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

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

评论

0赞 Jens Jansson 2/19/2009
是的,这确实奏效了。我试图在if中加入(Bar bar = foo.getBar()) !=null,但是java似乎不喜欢在if子句中初始化对象。谢谢!
0赞 Michael Borgwardt 2/4/2022
@zafar142003它与原始变量的工作方式完全相同。
7赞 TofuBeer 2/19/2009 #3

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

void foo()
{
    // some code ...

    // this block limits the scope of "Bar bar" so that the rest of the method cannot see 
    // it.
    {
        Bar bar;
        if(foo!=null && (bar = foo.getBar())!=null){
            System.out.println("Success: " + bar);
        } else {
            System.out.println("Failiure.");
        }
    }
}

如果有意义,您可能还需要签入 null 对象模式。如果可以的话,我个人会尽量避免事情无效......真的想想你是否希望允许 null。

2赞 Aaron Digulla 2/19/2009 #4

来自“我的编程语言比你的编程语言更好”部门: 在Groovy中,你可以使用“?.”运算符:

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

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

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

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

2赞 Tom Hawtin - tackline 2/19/2009 #5

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

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

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

表达式的副作用往往会导致代码错误。更喜欢更多、更简单的线路,而不是更少的、有缺陷的线路。如果用于在访问缓冲区时递增索引,或类似的迭代器样式算法,则通常会出现异常。++

0赞 Felipe Gomes 3/22/2018 #6

实际上,我认为这是使用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);
      });
  }
0赞 Jan Nielsen 7/22/2021 #7

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

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

但它并不漂亮。我完全同意汤姆·霍廷(Tom Hawtin)的评论。