我正在通过 AP Comp Sci 练习测试并发现以下问题:
什么是输出:
System.out.println("1" + new Integer(2) + 3);
答案是
123,
我很困惑,因为new Integer(2)
尚未将其转换为字符串,因此new Integer(2) + 3
如果两个部分都是整数,为什么 java 编译器认为该语句是字符串连接?
加法是左结合的。a + b + c == (a + b) + c
答案是否与操作顺序一样简单,这意味着该语句从左到右进行评估,以便它可以阅读。System.out.println("1" + new Integer(2).toString() + 3.toString());
首先,正如那家伙指出的那样,加法是左结合的。
其次,“1”+2的重载解析是由左操作数控制的,它是一个String。这强制连接,结果是“12”。
现在,“12”+ 3 经历了完全相同的重载决议,得到“123”。
原来的问题是:
System.out.println("1" + new Integer(2) + 3);
为什么这给了我们“123”;我假设提问者的意思不是 6 或“15”?
让我们简化它并将新的 Integer 位删除为其等效项:
System.out.println("1" + 2 + 3);
Java 语言规范 12 给出了答案(4.2.2):
字符串连接运算符 +(第 15.18.1 节),当给定一个字符串操作数和一个整数操作数时,它将整数操作数转换为字符串(字节、短、整数或长操作数的十进制形式,或字符操作数的字符),然后生成一个新创建的字符串,它是两个字符串的连接。https://docs.oracle.com/javase/specs/
15.18.1 部分更加清晰:
加法运算符具有相同的优先级并且在语法上是左结合的(它们从左到右分组)。如果 + 运算符的任一操作数的类型是字符串,则该操作是字符串连接。 https://docs.oracle.com/javase/specs/
因此,由于运算符 + 在这两种情况下都使用,它从左到右评估,无论是连接还是加法,如 15.18.1 中所述以及其他回答者所述。第一个操作数“1”是一个字符串,第二个操作数是一个整数 2,所以根据上面的规则,整数 2 被转换为一个字符串“2”,加号被解释为连接,给我们一个字符串“12”。然后它有一个字符串“12”和一个整数3,所以整数3按照上面的规则转换,+再次被解释为连接,我们得到一个字符串“123”。
如果他们在 2 + 3 周围加上括号:
System.out.println("1" + (2 + 3));
显然,这将迫使 2 + 3 首先被评估。它们都是整数,所以你得到一个整数 5。然后我们将有“1”+5,这是一个字符串加一个整数,所以整数被转换为一个字符串“5”,它们被连接起来,产生“15” .
如果他们改变了这样的顺序:
System.out.println(2 + 3 + "1");
然后,2 + 3 将按照从左到右的规则首先完成,因为它们都是整数,所以 + 表示加法,这将产生一个整数 5。然后我们将有运算符整数 5 和一个字符串“1”。根据上述规则,整数 5 被转换为字符串 5,+ 被解释为连接,我们得到一个字符串“51”。
所以这一切都归结为操作的顺序,所有这些操作实际上都是二进制的(一次只需要两个),并且,当使用加号时,如果一个操作数是一个字符串,另一个被更改为一个字符串,如果它不是一个,加号被解释为连接,结果是一个字符串。