字符连接形成一个string给出不同的结果
为什么,当我使用下面的操作来总结字符时,是否返回数字而不是字符? 它不应该给出相同的结果吗?
ret += ... ; // returns numbers ret = ret + ...; // returns chars
下面的代码重复字符:
doubleChar(“The”)→“TThhee”
public String doubleChar(String str) { String ret = ""; for(int i = 0; i < str.length(); i++) { ret = ret + str.charAt(i) + str.charAt(i); // it concatenates the letters correctly //ret += str.charAt(i) + str.charAt(i); // it concatenates numbers } return ret; }
以下expression式的结果
ret + str.charAt(i) + str.charAt(i);
是string连接的结果。 Java语言规范说明
string连接的结果是对两个操作数string串联的String对象的引用。 左侧操作数的字符位于新创build的string中右侧操作数的字符之前。
结果
str.charAt(i) + str.charAt(i);
是加法运算符应用于两种数字types的结果。 Java语言规范说明
二进制+运算符在应用于数字types的两个操作数时执行加法,产生操作数的总和。 […]数字操作数上的加法expression式的types是其操作数的升级types。
在这种情况下
str.charAt(i) + str.charAt(i);
成为一个int
保存两个char
值的和。 然后连接到ret
。
您可能也想知道关于复合赋值expression式+=
E1 op= E2
的复合赋值expression式等价于E1 = (T) ((E1) op (E2))
,其中T
是E1
的types,只是E1
只计算一次。
换一种说法
ret += str.charAt(i) + str.charAt(i);
相当于
ret = (String) ((ret) + (str.charAt(i) + str.charAt(i))); | ^ integer addition | ^ string concatenation
在你的第一个例子中,你明确地添加一个string作为第一个术语。 这迫使第二和第三届也被提升为string。 在第二种情况下,您要添加两个字符(然后将其附加到string) – 直到赋值后才会将其提升为string。 你可能已经明确,通过使用Character.toString()或String.valueOf()像这样
ret += Character.toString(str.charAt(i)) + String.valueOf(str.charAt(i));
第一个例子
从语义上讲,我会说我们正在研究arithmetic promotion
。 注意第一个例子:
String + char + char
由于算术推广,这两个char
值被提升为 String
值,所以types变成:
String + String + String
+
被重载,因为所有操作数都是String
types,所以执行连接。
第二个例子
在第二个例子中,与所有赋值一样,我们首先评估=
运算符的右边,我们有什么?
char + char
该字符被解释为它的数值,因为没有String
引起提升,并且我们有一个数字加法,然后被附加到String
。
额外阅读
算术推广的一些注意事项可以在这里find。
expression评估的一些注意事项可以在这里find。
从Java规范 :
15.26.2。 复合分配算子
E1 op= E2
的复合赋值expression式等价于E1 = (T) ((E1) op (E2))
,其中T
是E1
的types,只是E1
只计算一次。
所以+=
操作符有一个内置的转换到目标types。
相比之下, 简单分配的条款说 :
15.26.1。 简单的作业操作员=
如果右操作数的types不能通过赋值转换(§5.2)转换为variables的types,则会发生编译时错误。
这里,
ret = ret + str.charAt(i) + str.charAt(i);
被视为string连接。
和
ret += str.charAt(i) + str.charAt(i);
被视为适应性操作。
ret = ret + str.charAt(i)+ str.charAt(i); // //正确地连接字母
这是因为ret是string,它与其他字符连接。
ret + = str.charAt(i)+ str.charAt(i); //它连接数字
这是因为编译器首先计算'str.charAt(i)+ str.charAt(i)',这可能会导致一个数字,然后将它与ret连接起来。 所以基本上我们评估左边,然后分配它。
希望它消除你的困惑。