Roni Castro
Roni Castro

Reputation: 2144

The concatenation of chars to form a string gives different results

Why, when I use the operation below to sum chars, does it return numbers instead of chars? Shouldn't it give the same result?

ret += ... ; // returns numbers

ret = ret + ...; // returns chars

The code below duplicates the 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;
}

Upvotes: 11

Views: 2399

Answers (5)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279970

The result of the following expression

ret + str.charAt(i) + str.charAt(i); 

is the result of String concatenation. The Java language specification states

The result of string concatenation is a reference to a String object that is the concatenation of the two operand strings. The characters of the left-hand operand precede the characters of the right-hand operand in the newly created string.

The result of

str.charAt(i) + str.charAt(i); 

is the result of the additive operator applied to two numeric types. The Java language specification states

The binary + operator performs addition when applied to two operands of numeric type, producing the sum of the operands. [...] The type of an additive expression on numeric operands is the promoted type of its operands.

In which case

str.charAt(i) + str.charAt(i); 

becomes an int holding the sum of the two char values. That is then concatenated to ret.


You might also want to know this about the compound assignment expression +=

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

In other words

ret += str.charAt(i) + str.charAt(i);

is equivalent to

ret = (String) ((ret) + (str.charAt(i) + str.charAt(i)));
                      |                ^ integer addition
                      |
                      ^ string concatenation

Upvotes: 11

Rakesh KR
Rakesh KR

Reputation: 6527

From the Java specification:

15.26.2. Compound Assignment Operators

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

So the += operator has a built-in cast to the destination type.

In contrast, the clause for simple assignment says:

15.26.1. Simple Assignment Operator =

A compile-time error occurs if the type of the right-hand operand cannot be converted to the type of the variable by assignment conversion (§5.2).

Here,

 ret = ret + str.charAt(i) + str.charAt(i);

is treated as a string concatination.

And

ret += str.charAt(i) + str.charAt(i);

is treated as aditive operation.

Upvotes: 1

christopher
christopher

Reputation: 27346

The First Example

From the semantics, I'd say we're looking at arithmetic promotion at work. Note the first example:

String + char + char

Due to arithmetic promotion, those two char values are promoted to String values, so the types become:

String + String + String

The + is overloaded, to perform concatenation because all operands are of type String.

The Second Example

In the second example, as with all assignments, we evaluate the right hand side of the = operator first, and what do we have?

char + char

The char is interpreted as its numerical value, because there is no String to cause promotion, and we have a numerical addition, which is then appended to the String.

Extra Reading

Some notes on arithmetic promotion can be found here.

Some notes on expression evaluation can be found here.

Upvotes: 2

Elliott Frisch
Elliott Frisch

Reputation: 201447

In your first example, you are explicitly adding a String as the first term. That forces the second and third term to also be promoted to String(s). In the second case, you are adding two characters (which are then appended to the String) - it does not promote to a String until the assignment. You could have been explicit, by using Character.toString() or String.valueOf() like so

ret += Character.toString(str.charAt(i)) + String.valueOf(str.charAt(i));

Upvotes: 2

Shivam Shah
Shivam Shah

Reputation: 524

ret = ret + str.charAt(i) + str.charAt(i); // // it concatenates the letters correctly

This is because ret is string snd it concatenates with the other characters.

ret += str.charAt(i) + str.charAt(i); // it concatenates numbers

This is because the compiler first evaluates 'str.charAt(i) + str.charAt(i)' which probably results in a number and then concatenates it with ret. So essentially we evaluate the left side and then assign it.

Hope it clears your confusion.

Upvotes: 0

Related Questions