当 Java 计算连词 (&&) 时,如果 exp1 为 false,它会计算 exp2 吗?

发布于 2025-01-08 18:23:11 字数 521 浏览 2 评论 0原文

我想知道是否可以保证在 Java 程序中,只要左侧的表达式 (exp1) 计算结果为 false,连词右侧的布尔表达式 (上面的 exp2) 就不会被计算。我想知道,因为我有一个如下所示的表达式:

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

如果 Java 在看到 后不能保证停止计算 (var != null && var.somePredicate()) var 为 null,那么它可能会尝试计算 var.somePredicate() ,这会抛出 NullPointerException。

所以我的问题是,Java 是否能保证某种行为?或者这样写会更安全

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

I'm wondering if it's guaranteed that in a Java program, the boolean expression on the right of a conjunction (exp2 above) will NOT be evaluated as long as the expression on the left (exp1) evaluated to false. I'm wondering because I have an expression like the following:

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

If Java is not guaranteed to stop evaluating (var != null && var.somePredicate()) after it sees that var is null, then it may try to evaluate var.somePredicate() which would throw a NullPointerException.

So my question is, does Java guarantee a certain behavior when it comes to this? Or would it be safer to write

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

魂ガ小子 2025-01-15 18:23:11

根据 Java 语言规范,15.23 条件- 和运算符&&

&& 运算符类似于 & (§15.22.2),但 仅当其右侧操作数的值等于左侧操作数为 true

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

From the Java Language Specification, 15.23 Conditional-And Operator &&:

The && operator is like & (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is true.

So the language spec guarantees that the right-hand side of your expression will not be evaluated if the left hand side is false.

谁人与我共长歌 2025-01-15 18:23:11

不,java 使用短路评估。如果 expr1false,则不会评估 expr2,因此您的 && 使用是完全安全的。

另外,如果您有 if (exp1 || exp2) { .. } - 如果 exp1true,则不会评估 exp2

No, java uses Short circuit evaluation. If expr1 is false, expr2 will not be evaluated, thus your && usage is perfectly safe.

Also, if you have if (exp1 || exp2) { .. } - exp2 will not be evaluated if exp1 is true.

煮酒 2025-01-15 18:23:11

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

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 计算结果为 false,它将跳转经过第二个 ifeq 指令直接进入 else 语句。

这称为短路评估。

Let us perform our own experiment by looking directly at the opcodes that are generated from this sample code:

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 generates:

   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

The relevant opcodes are ifeq for my small program. They check to see if the variables are equal to 0, and jump a certain number of operations forward if they are, in this case, to opcode 23. So if the first ifeq evaluates to false it will jump past the second ifeq instruction straight to the else statement.

This is called short circuit evaluation.

§普罗旺斯的薰衣草 2025-01-15 18:23:11

如果您使用 &&或 ||,java 将使用短路求值(即,除非需要,否则不求值第二个表达式

)或 |,java 将始终计算第二个表达式,即使第一个表达式为 true

If you use && or ||, java will use short-circuit evaluation (ie not evaluate the second expression unless it needs to)

If you use & or |, java will always evaluate the second expression, even if the first was true

十年不长 2025-01-15 18:23:11

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

That's safe, Java does short circuit evaluations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文