Компилятор преобразует эту фразу ("x =" + x) в StringBuilder для внутреннего использования и использует .append (int) для "добавления" целого числа в строку.
Чтобы выйти за рамки практического «как Java это делает», я приму совет Стивена и приведу теоретическое. Концептуально каждое значение в конкатенации сначала преобразуется в строку, а затем конкатенируется. Нули объединяются как слово «ноль».
Из спецификации языка Java :
15.18.1.1 Преобразование строки
Любой тип может быть преобразован в тип String путем преобразования строки. Ценность
х примитивного типа Т сначала преобразуется в опорное значение, как будто
давая его в качестве аргумента для создания соответствующего экземпляра класса
выражение:
Если T булево, тогда используйте новый булево (x). Если T - символ, тогда используйте новый
Характер (х). Если T является байтом, коротким или целым числом, используйте новое целое число (x). Если
T длинный, затем используйте новый Long (x). Если T - float, тогда используйте новый Float (x).
Если T двойное, то используйте новый Double (x). Это эталонное значение тогда
преобразован в тип String путем преобразования строки. Теперь только ссылка
значения должны быть рассмотрены. Если ссылка является нулевой, это
преобразуется в строку «null» (четыре символа ASCII n, u, l, l).
В противном случае преобразование выполняется как будто путем вызова
метод toString ссылочного объекта без аргументов; но если
результат вызова метода toString равен нулю, тогда строка "пусто"
используется вместо.
Метод toString определяется изначальным классом Object; много
классы переопределяют его, в частности, Boolean, Character, Integer, Long, Float,
Двойной и струнный.
15.18.1.2 Оптимизация конкатенации строк
Реализация может выбрать выполнение преобразования и объединения
за один шаг, чтобы избежать создания, а затем отказаться от промежуточного
Строковый объект. Для увеличения производительности повторяющейся строки
конкатенации, компилятор Java может использовать класс StringBuffer или
аналогичная техника для уменьшения количества промежуточных строковых объектов
которые создаются путем оценки выражения. Для примитивных типов,
реализация также может оптимизировать создание оболочки
объект путем преобразования непосредственно из примитивного типа в строку.
Оптимизированная версия на самом деле не будет выполнять полное преобразование строк вначале.
Это хорошая иллюстрация оптимизированной версии, используемой компилятором, хотя и без преобразования примитива, где вы можете видеть, как компилятор превращает вещи в StringBuilder в фоновом режиме:
http://caprazzi.net/posts/java-bytecode-string-concatenation-and-stringbuilder/
Этот код Java:
public static void main(String[] args) {
String cip = "cip";
String ciop = "ciop";
String plus = cip + ciop;
String build = new StringBuilder(cip).append(ciop).toString();
}
Создает это - посмотрите, как два стиля объединения приводят к одному и тому же байт-коду:
L0
LINENUMBER 23 L0
LDC "cip"
ASTORE 1
L1
LINENUMBER 24 L1
LDC "ciop"
ASTORE 2
// cip + ciop
L2
LINENUMBER 25 L2
NEW java/lang/StringBuilder
DUP
ALOAD 1
INVOKESTATIC java/lang/String.valueOf(Ljava/lang/Object;)Ljava/lang/String;
INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
ALOAD 2
INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;
ASTORE 3
// new StringBuilder(cip).append(ciop).toString()
L3
LINENUMBER 26 L3
NEW java/lang/StringBuilder
DUP
ALOAD 1
INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
ALOAD 2
INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;
ASTORE 4
L4
LINENUMBER 27 L4
RETURN
Компилятор преобразовал "cip + ciop" в "новый StringBuilder (cip) .append (ciop) .toString ()". Другими словами, «+» фактически является сокращением для более многословной идиомы StringBuilder.