Из Fine Manual :
Язык Java обеспечивает специальную поддержку оператора конкатенации строк (+) и преобразования других объектов в строки. Объединение строк реализуется с помощью класса
StringBuilder
(илиStringBuffer
) и его методаappend
. Преобразования строк реализуются с помощью метода toString, определенного Object и наследуемого всеми классами в Java.Для получения дополнительной информации о конкатенации и преобразовании строк см. Gosling, Joy и Steele, Спецификация языка Java .
См. Конкатенация строк в JLS.
Это особое поведение, задокументированное в спецификации языка .
15.18.1 Оператор конкатенации строк +
Если только одно выражение операнда имеет тип String, тогда преобразование строки выполняется для другого операнда, чтобы получить строка во время выполнения. Результатом является ссылка на объект String (вновь созданный, если только выражение не является выражением константы времени компиляции (§15.28)), который является конкатенация двух строк операндов . Символы левого операнда предшествуют символам правого операнда во вновь созданной строке. Если операнд типа String имеет значение null, то строка "null" используется вместо этого операнда.
Большинство ответов здесь правильные (это обрабатывается компилятором, + преобразуется в .append()...)
Я хотел добавить, что каждый должен когда-нибудь взглянуть на исходный код String и append, он довольно впечатляющий.
Я полагаю, что это сводится к чему-то вроде:
"a"+"b"+"c"
=
new String().append("a").append("b").append("c")
Но затем происходит какая-то магия. Это превращается в:
В то время как большинство людей считают, что он создаст "ab", а затем отбросит его, когда он создаст "abc". На самом деле он понимает, что его соединяют в цепочку, и выполняет некоторые манипуляции.
Существует также трюк, когда если у вас есть строка "abc" и вы просите подстроку, которая оказывается "bc", они могут использовать один и тот же базовый массив. Вы заметите, что есть начальная позиция, конечная позиция и флаг "общий".
На самом деле, если он не является общим, то возможно, что он увеличит длину строки и скопирует остальные.
Теперь я просто запутался. Почитайте исходный код - он довольно крутой.
Это делается на уровне языка. Спецификация языка Java очень специфична в отношении того, что должно происходить при добавлении строк .
Строка
определяется как стандартный тип, как int, double, float и т. Д. На уровне компилятора. По сути, все компиляторы имеют перегрузку операторов. Перегрузка операторов не определена для разработчиков (в отличие от C ++).
Интересно: этот вопрос был зарегистрирован как ошибка: http://bugs.sun.com/view_bug.do?bug_id=4905919
Компилятор обрабатывает ваш код так, как если бы вы написали что-то вроде:
String both = new StringBuilder().append(ab).append(cd).toString();
Edit: Any reference? Ну, если я компилирую и декомпилирую код OP, я получаю следующее:
0: ldc #2; //String ab
2: astore_1
3: ldc #3; //String cd
5: astore_2
6: new #4; //class java/lang/StringBuilder
9: dup
10: invokespecial #5; //Method java/lang/StringBuilder."<init>":()V
13: aload_1
14: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
18: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
25: return
Итак, все так, как я сказал.