Java can\'t do operator overloading, but +
works okay for String
and Integer
and some other classes. How is this possible?
The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings.
String s = "string 1" + "string 2";
What actually is execute is
(new StringBuilder()).append("string 1").append("string 2").toString()
+
is a built-in operation. It's an exception, not a rule.
+
is not an example of operator overloading. +
is built into the language as a concatentation operator and an arithmetic-addition operator.
What this means is that a person writing a program with Java cannot overload operators, but as far as the grammar of the Java language is concerned, +
is defined as a concatenation and an addition operator.
EDIT
It works for other classes such as Integer
and Double
because of autoboxing.
If you take a look at the bytecode of a Java program that performs string concatenation, you'll see that it creates StringBuilder
and uses the append()
method. The Java compiler sees the +
operator and realizes that the operands are strings and not primitive types (like int
).
If you look at the bytecode of a program that does integer addition, you will see that it uses the iadd
instruction to perform integer addition. This is because the compiler realizes that the operands to the +
operation are integers.
As far as doing something like Integer i = 4
, the bytecode will show that you're actually doing Integer i = Integer.valueOf(4)
. This is called autoboxing. Later on, when you do something like i + p
, where both i
and p
are of type Integer
, the generated bytecode will show that you're doing i.intValue() + p.intValue()
, where the return types of both methods are int
(the actual bytecode instruction again, is iadd
).
This is why +
works Integer
even though they are not actual primitive types.
As @yan said, this is the exception, not the rule. Strings have a special status in Java. There's a whole subsection of the Java Language Specification devoted to +
in its role as the string concatenation operator: §15.18.1.
Regarding your update, that's another special case. Java is sometimes, depending on the case, smart enough to convert things that are not String
s into String
s when String
s are needed. One of these special cases is the one you described, where primitives are showing up in a place that needs a String
. The primitives are first converted to their reference types — Integer
, Double
, &c. — and then into String
s via the toString()
method.
Another special case is when one String
and one non-String
are being combined with the string concatenation operator +
, as described in JLS §5.4 — String Conversion.
For completeness: +
in its more common "adding numbers together" role is described in the other part of of §15.18, §15.18.2 — Additive Operators (+ and -) for Numeric Types.
Java doesn't allow custom operator overloading, but the compiler can still be told by the compiler developer that String1 + String2 == String1String2, and to substitute the proper concatenation method call for the + operator.
It works for primitive wrappers like Integer because of autoboxing.
It works for String because that's a special case for concatenating strings:
The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method. String conversions are implemented through the method toString, defined by Object and inherited by all classes in Java. For additional information on string concatenation and conversion, see Gosling, Joy, and Steele, The Java Language Specification.