上次考试我们做了一个练习,要求确定以下代码的输出:
System.out.println(2 + 3 + ">=" + 1 + 1);
我的答案是5 >= 2
,但现在我意识到这是错误的。正确答案应该是5 >= 11
。
为什么呢?
上次考试我们做了一个练习,要求确定以下代码的输出:
System.out.println(2 + 3 + ">=" + 1 + 1);
我的答案是5 >= 2
,但现在我意识到这是错误的。正确答案应该是5 >= 11
。
为什么呢?
假设你的语法是:
System.out.println(2 + 3 + ">=" + 1 + 1);
表达式从左到右进行评估,在这种情况下,2 + 3相加为5,当与字符串“ added”相加时会产生"5 >="
,当添加到1时会变成"5 >= 1"
,再加上1,你的结果就是:"5 >= 11"
+
和 *
),其中一个首先被处理时发生的情况。这里起作用的是从左到右的结合性。 - Karl Knechtel因为将字符串"添加"到任何东西上都会导致连接。以下是它在编译阶段如何评估:
((((2 + 3) + ">=") + 1) + 1)
编译器将进行常量折叠,因此编译器实际上可以逐个减少表达式,并替换为常量表达式。然而,即使它没有这样做,运行时路径也会有效地相同。所以这里是:
((((2 + 3) + ">=") + 1) + 1) // original
(((5 + ">=") + 1) + 1) // step 1: addition (int + int)
(("5>=" + 1) + 1) // step 2: concatenation (int + String)
("5>=1" + 1) // step 3: concatenation (String + int)
"5>=11" // step 4: concatenation (String + int)
你可以通过使用圆括号将第二个数值相加的表达式分组,来强制进行整数加法。例如:
System.out.println(2 + 3 + ">=" + 1 + 1); // "5>=11"
System.out.println(2 + 3 + ">=" + (1 + 1)); // "5>=2"
Number+number=number
number+string=string
string+number=string
etc.
从左到右进行运算。你将"1"
与"5 >="
连接起来,最终再将"1"
与"5 >= 1"
连接起来。
让我们从左到右逐个令牌阅读:
遇到的第一个文字是整数2
,然后是+
,然后是另一个整数3
。两个整数之间的+
是加法,因此它们相加得到5
。
现在我们有了5
,一个整数,然后是+
,然后是一个字符串">="
。整数和字符串之间的+
是连接运算符。因此,这些字符串组合在一起形成"5>="
。
然后我们有"5>="
,一个字符串,一个+
,然后是一个整数1
。这又是字符串连接。因此结果是"5>=1"
。
最后,我们有"5>=1"
,一个字符串,一个+
,然后是1
。这又是字符串连接。因此结果是"5>=11"
。