+ is left-associative, so
a + b + c
is always evaluated as
(a + b) + c
The rules at play in deciding how the + operator is applied are JLS 15.18:
- If just one operand to
+ is a String, the other operand is converted to a string, and then string concatenation is used.
- If both operands are numbers (or convertible to numbers by unboxing), the operands undergo binary numeric promotion, and then they are numerically added.
- Otherwise, compiler error.
Taking your examples in turn:
(1 + 2) + "3"
first evaluates (1 + 2), and they're both numbers, so numeric addition applies: they're the same type, so they remain ints after binary numeric promotion, yielding 3.
3 + "3"
The second operand is a String, so the first is converted to a String, and then the two strings are concatenated:
"33"
(1 + 2) + '3'
Same thing happens for the (1+2) = 3.
'3' is a char, which is a numeric type, so 3 and '3' undergo binary numeric promotion to int, and then are numerically added. (int) '3' == 51, so 3 + 51 = 54.