当Java计算一个连词(<boolean exp1 =“”>&amp;&amp; <boolean exp2 =“”>)时,如果exp1为假,它是否eval exp2?</boolean> </boolean>

时间:2012-02-25 15:06:25

标签: java conditional boolean expression evaluation

我想知道是否保证在Java程序中,只要左边的表达式(exp1)评估为false,就不会计算连接右边的布尔表达式(上面的exp2)。我想知道因为我有如下表达式:

if (var != null && var.somePredicate())
   // do something

如果不确定Java在(var != null && var.somePredicate())为空后才停止评估var,那么它可能会尝试评估会引发NullPointerException的var.somePredicate()

所以我的问题是,Java在这方面是否保证某种行为?或者编写

会更安全
if (var != null)
{
   if (var.somePredicate())
      // do something
}

5 个答案:

答案 0 :(得分:6)

来自Java语言规范,15.23 Conditional-And Operator &&

  

&&运算符类似于&(第15.22.2节),但仅在其左侧操作数的值为真时才计算其右侧操作数

因此语言规范保证如果左侧是假的,则不会评估表达式的右侧。

答案 1 :(得分:4)

不,java使用Short circuit evaluation。如果expr1false,则不会评估expr2,因此您&&的使用非常安全。

此外,如果if (exp1 || exp2) { .. } - exp2exp1true,则不会对其进行评估。

答案 2 :(得分:2)

让我们直接查看从此示例代码生成的操作码来执行我们自己的实验:

public class Compare {

        public static void main(String... args) {
          boolean t = true;
          boolean f = false;
          if(f && t) {
            System.out.println("Both true");
          }
          else {
            System.out.println("One false");
          }
        }

}

javap -v生成:

   0:   iconst_1
   1:   istore_1
   2:   iconst_0
   3:   istore_2
   4:   iload_2
   5:   ifeq    23
   8:   iload_1
   9:   ifeq    23
   12:  getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   15:  ldc #3; //String No
   17:  invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   20:  goto    31
   23:  getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   26:  ldc #5; //String Yes
   28:  invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   31:  return

我的小程序的相关操作码为ifeq。他们检查变量是否等于0,并且如果它们是操作码23,则向前跳转一定数量的操作。因此,如果第一个ifeq评估为假,它将跳过第二个ifeq直接指示else语句。

这称为短路评估。

答案 3 :(得分:1)

如果您使用&amp;&amp;或者||,java将使用短路评估(即除非需要,否则不评估第二个表达式)

如果您使用&amp;或者|,java将始终评估第二个表达式,即使第一个表达式为真

答案 4 :(得分:0)

这是安全的,Java会进行短路评估。