短路求值与多个if语句

4
这是什么区别:

这是什么区别:

if(a && b)
{
     //code
}

并且这样做:

if(a)
{
     if(b)
     {
          //code
     }
}

据我所知,如果 a 为真,则仅在第一个代码块中评估 b,而第二个代码块将是相同的情况。
使用其中之一是否有任何好处?代码执行时间?内存?等等。

@DavidSchwartz 好吧,你必须选择一个,不如选择更好的那个,即使出于任何原因,即使仅仅是代码可读性,而不一定是执行时间。 - Aequitas
没错。所以忘记代码执行时间或内存。应该选择更清晰表达程序员意图的那个。 - David Schwartz
抢占式微优化从来不是一个好主意。95%的情况下,微优化没有任何作用。如果你要进行微优化,首先要确定你有瓶颈,然后对代码进行分析,做出调整,测量并确保它们有效。当你编写代码时,可读性非常重要。 - Anubian Noob
这是非常主观的。一般来说,编写依赖于短路(即将方法调用作为&&的第二个操作数)的代码会很令人困惑。但如果你只有两个变量,那就没关系了。同样,这也是非常主观的。 - Anubian Noob
例如,如果ab只是布尔值,那么(a && b)可能更好。但是,如果b实际上是一个函数调用,并且//code并不重要强调,第二个选项可能更好,因为它强调了调用b的条件,并为您提供了对b进行注释的位置。 - David Schwartz
显示剩余2条评论
4个回答

8

它们被编译成相同的字节码,没有性能差异。

可读性是唯一的区别。作为一个巨大的概括,短路看起来更好,但嵌套略微更清晰。这真的取决于具体的用例。我通常会使用短路。


我试过了。这是代码:

public class Test {

    public static void main(String[] args) {
        boolean a = 1>0;
        boolean b = 0>1;

        if (a && b)
            System.out.println(5);

        if (a)
            if (b)
                System.out.println(5);
    }
}

这将编译为:

  0: iconst_1
  1: istore_1
  2: iconst_0
  3: istore_2
  4: iload_1
  5: ifeq          19
  8: iload_2
  9: ifeq          19
 12: getstatic     #2
 15: iconst_5
 16: invokevirtual #3
 19: iload_1
 20: ifeq          34
 23: iload_2
 24: ifeq          34
 27: getstatic     #2
 30: iconst_5
 31: invokevirtual #3
 34: return

请注意此块内容重复了两次:
  4: iload_1
  5: ifeq          19
  8: iload_2
  9: ifeq          19
 12: getstatic     #2
 15: iconst_5
 16: invokevirtual #3

两次都有相同的字节码。


4

如果每个if都有一个关联的else,那么就会产生不同。

if(a && b)
{
     //do something if both a and b evaluate to true
} else {
    //do something if either of a or b is false
}

还有这个:

if(a)
{
     if(b)
     {
          //do something if both a and b are true
     } else {
          //do something if only a is true
     }
} else {
     if(b)
     {
          //do something if only b is true
     } else {
          //do something if both a and b are false
     }
}

0
如果在您的第二个示例中两个if语句之间没有任何内容,那么第一个示例肯定更清晰、更易读。
但是,如果有一段代码可以适合放在两个if条件之间,那么只有第二个示例才是正确的方式。

如果您有一些代码需要在 a 之后但在 b 之前运行,那么您可以将其放入一个名为 c 的方法中,并使其返回 true。然后,您可以使用短路符号 a && c() && b。 - emory

0

应该没有区别,但从可读性考虑,我更喜欢第一个,因为它不太冗长也不太缩进。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接