为什么当我使用下面的操作来计算字符数时,它会返回数字而不是字符吗?它不应该给出相同的结果吗?
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;
}
答案 0 :(得分:11)
以下表达式的结果
ret + str.charAt(i) + str.charAt(i);
是字符串连接的结果。 The Java language specification states
字符串连接的结果是对String对象的引用 这是两个操作数字符串的串联。那些角色 左手操作数的前面是右手的字符 新创建的字符串中的操作数。
的结果
str.charAt(i) + str.charAt(i);
是将加法运算符应用于两种数值类型的结果。 The Java language specification states
二进制+运算符在应用于两个操作数时执行加法 数字类型,生成操作数的总和。 [...] 数字操作数上的加法表达式的类型是提升 其操作数的类型。
在哪种情况下
str.charAt(i) + str.charAt(i);
成为int
,其中包含两个char
值的总和。然后将其连接到ret
。
您可能还想知道有关复合赋值表达式+=
E1 op= E2
形式的复合赋值表达式是等效的 到E1 = (T) ((E1) op (E2))
,其中T
是E1
的类型,E1
除外 仅评估一次。
换句话说
ret += str.charAt(i) + str.charAt(i);
相当于
ret = (String) ((ret) + (str.charAt(i) + str.charAt(i)));
| ^ integer addition
|
^ string concatenation
答案 1 :(得分:2)
第一个例子
从语义上讲,我会说我们在工作时看arithmetic promotion
。请注意第一个例子:
String + char + char
由于算术推广,这两个char
值被提升到String
值,因此类型变为:
String + String + String
+
被重载,以执行连接,因为所有操作数都是String
类型。
第二个例子
在第二个示例中,与所有分配一样,我们首先评估=
运算符的右侧,我们有什么?
char + char
char被解释为它的数值,因为没有String
引起提升,我们有一个数字加法,然后附加到String
。
额外阅读
可以找到关于算术推广的一些注释here。
可以找到关于表达评估的一些注释here。
答案 2 :(得分:2)
在第一个示例中,您明确添加了一个String作为第一个术语。这迫使第二和第三项也被提升为String(s)。在第二种情况下,您将添加两个字符(然后将其附加到字符串) - 在分配之前,它不会提升为String。您可以明确地使用Character.toString()或String.valueOf()这样
ret += Character.toString(str.charAt(i)) + String.valueOf(str.charAt(i));
答案 3 :(得分:1)
15.26.2。复合赋值运算符
E1 op= E2
形式的复合赋值表达式等同于E1 = (T) ((E1) op (E2))
,其中T
是E1
的类型,但E1
仅被评估一次。
因此+=
运算符具有对目标类型的内置强制转换。
相比之下,clause for simple assignment says:
15.26.1。简单分配操作符=
如果右侧操作数的类型无法通过赋值转换(第5.2节)转换为变量类型,则会发生编译时错误。
下面,
ret = ret + str.charAt(i) + str.charAt(i);
被视为字符串连接。
和
ret += str.charAt(i) + str.charAt(i);
被视为加法操作。
答案 4 :(得分:0)
ret = ret + str.charAt(i)+ str.charAt(i); // //它正确连接字母
这是因为ret是字符串,它与其他字符连接。
ret + = str.charAt(i)+ str.charAt(i); //它连接数字
这是因为编译器首先评估&#;; str.charAt(i)+ str.charAt(i)&#39;这可能导致一个数字,然后与ret连接。所以基本上我们评估左侧然后分配它。
希望它能清除你的困惑。