形成字符串的字符串联会产生不同的结果

时间:2014-01-27 17:48:27

标签: java string char concatenation

为什么当我使用下面的操作来计算字符数时,它会返回数字而不是字符吗?它不应该给出相同的结果吗?

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;
}

5 个答案:

答案 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)),其中TE1的类型,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)

来自Java specification

  

15.26.2。复合赋值运算符

     

E1 op= E2形式的复合赋值表达式等同于E1 = (T) ((E1) op (E2)),其中TE1的类型,但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连接。所以基本上我们评估左侧然后分配它。

希望它能清除你的困惑。