string和字符的连接
以下声明,
String string = "string"; string = string +((char)65) + 5; System.out.println(string);
产生输出stringA5
。
但是,以下,
String string = "string"; string += ((char)65) + 5; System.out.println(string);
产生string70
。
区别在哪里?
由于运算符优先级和string转换的组合,您会看到此行为。
JLS 15.18.1规定:
如果只有一个操作数expression式是Stringtypes,则在另一个操作数上执行string转换(第5.1.11节)以在运行时产生string。
因此,第一个expression式中的右侧操作数被隐式转换为string: string = string + ((char)65) + 5;
对于第二个expression式, string += ((char)65) + 5;
必须将+=
复合赋值运算符与+
一起考虑。 由于+=
弱于+
,因此首先计算+
运算符。 在那里我们有一个char
和一个int导致二进制数字提升为int
。 只有+=
被评估,但此时涉及+
运算符的expression式的结果已经被评估。
情况1
string = string +((char)65) + 5;
一切都被视为string,但在第二种情况
操作顺序:
-
string +((char)65 = stringA
-
stringA + 5 = stringA5
案例2
string += ((char)65) + 5;
((char)65) + 5
,则((char)65) + 5 is 70
,之后+ =运算。
操作顺序:
-
(char)65 + 5 = 70
-
string + 70 = string70
让我们再看一个例子
String string = "string"; string += ((char)65) + 5 + "A"; System.out.println(string);
输出 string70A
原因相同的第一个右边是计算的,并且执行的操作是不一致的
-
(char)65 + 5 = 70
-
70 + "A" = 70A
-
string + 70A = string70A
当你写:
string = string + ((char)65) + 5;
这就像写作:
String string = new StringBuilder(string).append((char)65).append((int)5).toString();
这就像将string
附加到A
(十进制65的char表示)和5
。
在后者中,首先计算右手,然后将结果添加到string
,就像写:
string = string + 70;
string = string +((char)65) + 5;
这意味着“将string设置为string的连接, ((char)65)
和5
。 这从左到右(如此第一个string + ((char)65)
进行评估,然后是+5
,并且string和整数的连接将该整数转换为string。
string += ((char)65) + 5;
这意味着“计算((char)65)+5
的结果并将其添加到string” – 在将结果添加到string之前对整个右侧进行求值。 由于char
实际上只是一个16位的整数,所以它将它们作为整数加在一起(给70),然后把它附加到string
。
和这个例子一样:
System.out.println("abc"+10 + 5);
产生abc105(添加为string)
和
System.out.println(5 + 10);
产生15个(添加为数字)
包含在(操作的第一位)中的Strings
在执行操作时强制将所有元素视为Strings
。 在你使用+=
的情况下,首先在右边部分执行操作(将元素视为int
),这是因为操作符优先,然后与String
连接。