Java 以什么顺序计算这个特定的表达式:System.out.println( "g." + " big " + 2*3);



是否首先计算 2*3,因为 * 具有更高的优先级或为"g"。+ "大 " 在计算 2*3 到 6 之前计算为 "g. big",因为表达式是从左到右读取的。

System.out.println("g."+ " big " + 2*3);

最终输出是g.big 6,但我更关心它的评估顺序。

这不是重复的,因为它不关注字符串和整数上的 + 操作。问题是"*"是否最终完成,因为它存在于"+"之后,当从(从左到右(读取表达式时可以轻松执行。

有点不同,以避免编译器做太多

static String a() { System.out.print("a "); return "0"; }
static String b() { System.out.print("b "); return "1"; }
static int c() { System.out.print("c "); return 2; }
static int d() { System.out.print("d "); return 3; }
public static void main(String... args) {
System.out.println(a() + b() + c() * d());
}

输出:

阿 乙 中 D 016

以及反汇编的代码:

public static void main(java.lang.String...);
Code:
0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
3: invokestatic  #10                 // Method a:()Ljava/lang/String;
6: invokestatic  #11                 // Method b:()Ljava/lang/String;
9: invokestatic  #12                 // Method c:()I
12: invokestatic  #13                 // Method d:()I
15: imul
16: invokedynamic #14,  0             // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String;
21: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
24: return

尽管操作数按从左到右的顺序计算,但首先完成乘法,然后完成串联。


这里从问题中反汇编代码:

System.out.println("g."+ " big " + 2*3);
Code:
0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc           #16                 // String g. big 6
5: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

确认了另一个Dave的回答和评论,编译器将整个操作简化为一个字符串"g. big 6"


使用 int 变量 (0:a, 1:b, 2:c, 3:d(:

System.out.println(a + b + c * d);
Code:
12: iload_0
13: iload_1
14: iadd
15: iload_2
16: iload_3
17: imul
18: iadd
19: invokevirtual #21                 // Method java/io/PrintStream.println:(I)V

在 java 中,*运算符的优先级高于+运算符。这导致语句的计算方式如下

第一步2 * 3 = 6

第二步"g."+ " big " = "g. big "

第三步"g. big " + 6 = "g. big 6"

您可以在此处阅读有关 Java 运算符顺序的更多信息

评估显然是从左到右的。

我想规范说"似乎是",因为在某些情况下,例如您发布的案例,如果不检查代码,您将无法真正分辨。 整个表达式可以在编译时进行评估,我希望是在编译时计算的。

这与优先级无关;优先级确定操作数是什么,而不是计算顺序。因此*的操作数是23,而不是g.big23

最新更新