If only one operand expression is of type String
, then string conversion is performed on the other operand to produce a string at run time. The result is a reference to a newly created 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.
Any type may be converted to type String
by string conversion.
A value x of primitive type T is first converted to a reference value as if by giving it as an argument to an appropriate class instance creation expression:
boolean
, then use new
Boolean(
x)
(§20.4).
char
, then use new
Character(
x)
(§20.5).
byte
, short
, or int
, then use new
Integer(
x)
(§20.7).
long
, then use new
Long(
x)
(§20.8).
float
, then use new
Float(
x)
(§20.9).
double
, then use new
Double(
x)
(§20.10).
This reference value is then converted to type String
by string conversion.
Now only reference values need to be considered. If the reference is null
, it is converted to the string "null
" (four ASCII characters n
, u
, l
, l
). Otherwise, the conversion is performed as if by an invocation of the toString
method of the referenced object with no arguments; but if the result of invoking the toString
method is null
, then the string "null
" is used instead. The toString
method (§20.1.2) is defined by the primordial class Object
(§20.1); many classes override it, notably Boolean
, Character
, Integer
, Long
, Float
, Double,
and String
.
An implementation may choose to perform conversion and concatenation in one
step to avoid creating and then discarding an intermediate String
object. To
increase the performance of repeated string concatenation, a Java compiler may
use the StringBuffer
class (§20.13) or a similar technique to reduce the number
of intermediate String
objects that are created by evaluation of an expression.
For primitive objects, an implementation may also optimize away the creation of a wrapper object by converting directly from a primitive type to a string.
"The square root of 2 is " + Math.sqrt(2)
"The square root of 2 is 1.4142135623730952"
The + operator is syntactically left-associative, no matter whether it is later determined by type analysis to represent string concatenation or addition. In some cases care is required to get the desired result. For example, the expression:
a + b + c
is always regarded as meaning:
(a + b) + c
Therefore the result of the expression:
1 + 2 + " fiddlers"
"3 fiddlers"
"fiddlers " + 1 + 2
"fiddlers 12"
In this jocular little example:
class Bottles { static void printSong(Object stuff, int n) { String plural = "s"; loop: while (true) { System.out.println(n + " bottle" + plural + " of " + stuff + " on the wall,"); System.out.println(n + " bottle" + plural + " of " + stuff + ";"); System.out.println("You take one down " + "and pass it around:"); --n; plural = (n == 1) ? "" : "s"; if (n == 0) break loop; System.out.println(n + " bottle" + plural + " of " + stuff + " on the wall!"); System.out.println(); } System.out.println("No bottles of " + stuff + " on the wall!"); }
}
the method printSong
will print a version of a children's song. Popular values
for stuff include "pop"
and "beer"
; the most popular value for n
is 100
. Here is
the output that results from Bottles.printSong("slime", 3)
:
3 bottles of slime on the wall, 3 bottles of slime; You take one down and pass it around: 2 bottles of slime on the wall! 2 bottles of slime on the wall, 2 bottles of slime; You take one down and pass it around: 1 bottle of slime on the wall! 1 bottle of slime on the wall, 1 bottle of slime; You take one down and pass it around: No bottles of slime on the wall!
In the code, note the careful conditional generation of the singular "bottle
" when appropriate rather than the plural "bottles
"; note also how the string concatenation operator was used to break the long constant string:
"You take one down and pass it around:"
into two pieces to avoid an inconveniently long line in the source code.