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;
}
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 toE1 = (T) ((E1) op (E2))
, whereT
is the type ofE1
, except thatE1
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
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));
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.
From the Java specification:
15.26.2. Compound Assignment Operators
A compound assignment expression of the form
E1 op= E2
is equivalent toE1 = (T) ((E1) op (E2))
, whereT
is the type ofE1
, except thatE1
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With