+ оператор для строки в Java

Я видел этот вопрос несколько минут назад и решил заглянуть в класс java String, чтобы проверить если была какая-то перегрузка для оператора +.

Я ничего не мог найти, но я знаю, что могу это сделать

String ab = "ab";
String cd = "cd";
String both = ab + cd; //both = "abcd"

Где это реализовано?


person Samuel Carrijo    schedule 24.02.2010    source источник


Ответы (7)


Из Fine Manual:

Язык Java обеспечивает специальную поддержку оператора конкатенации строк ( + ) и преобразования других объектов в строки. Конкатенация строк реализуется через класс StringBuilder(или StringBuffer) и его метод append. Преобразования строк реализуются через метод toString, определенный Object и наследуемый всеми классами в Java. Дополнительную информацию о конкатенации и преобразовании строк см. в статье Гослинг, Джой и Стил, Спецификация языка Java.

См. раздел объединение строк в JLS.

person Josh Lee    schedule 24.02.2010
comment
StringBuilder следует отдавать предпочтение, если синхронизация не имеет значения. - person gpampara; 25.02.2010
comment
@gpampara Компилятор знает, как использовать StringBuilder. StringBuffer использовался в старых версиях до появления StringBuilder. - person Paŭlo Ebermann; 30.07.2013

Компилятор обрабатывает ваш код так, как если бы вы написали что-то вроде:

String both = new StringBuilder().append(ab).append(cd).toString();

Изменить: любая ссылка? Что ж, если я скомпилирую и декомпилирую код ОП, я получу следующее:

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

Итак, все как я сказал.

person Sean    schedule 24.02.2010

Большинство ответов здесь верны (это обрабатывается компилятором, + преобразуется в .append()...)

Я хотел добавить, что каждый должен взглянуть на исходный код для String и в какой-то момент добавить его, это довольно впечатляюще.

Я считаю, что это сводилось к чему-то вроде:

"a"+"b"+"c"

=

new String().append("a").append("b").append("c")

Но потом происходит какое-то волшебство. Это превращается в:

  • Создайте массив строк длины 3
  • скопируйте a в первую позицию.
  • скопировать б во второй
  • скопировать c в третий

Принимая во внимание, что большинство людей считают, что он создаст «ab», а затем выбросит его, когда он создаст «abc». Он на самом деле понимает, что его приковывают, и делает некоторые манипуляции.

Существует также трюк, когда, если у вас есть строка «abc», и вы запрашиваете подстроку, которая оказывается «bc», они МОГУТ использовать один и тот же базовый массив. Вы заметите, что есть начальная позиция, конечная позиция и «общий» флаг.

На самом деле, если он не используется совместно, он может увеличить длину строки и скопировать в нее остальные.

Сейчас я просто путаюсь. Прочтите исходный код — это довольно круто.

person Bill K    schedule 24.02.2010
comment
Нет new String().append("a").append("b").append("c"), а new StringBuilder().append("a").append("b).append("c").toString(). Способ no-stringbuilder будет "a".concat("b").concat("c"), и это неэффективный способ, как вы описали. (Но при использовании + с константами времени компиляции все это уже сделано компилятором.) - person Paŭlo Ebermann; 30.07.2013

Он обрабатывается компилятором.

person Fredrik    schedule 24.02.2010
comment
Впечатляющий ответ. Вы не думали стать учителем? - person whiskeysierra; 24.02.2010
comment
@Willi Schönborn: Ну, это простой и правильный ответ. У меня не было времени написать больше, когда я написал это, и когда я вернулся к компьютеру, было много ответов, объясняющих это более подробно. Извините, но я не вижу смысла дублировать другие ответы, я рекомендую прочитать @Sean's и @jleedev, если вам нужна дополнительная информация (и да, преподавание есть в моем резюме). - person Fredrik; 25.02.2010
comment
Дело в том, что ваш ответ настолько общий, что он подходит почти для ~ 75% всех вопросов, связанных с Java, на SO. - person whiskeysierra; 25.02.2010
comment
@Will Schönborn 75% всех проблем с Java не обрабатываются компилятором. Фактически, в большинстве случаев компилятор просто компилирует исходный код в байтовый код. Несколько исключений — это оператор + для String и несколько вещей, результатом которых является встраивание встроенной функции. Мой ответ был первым с единственной целью - быть быстрым ответом, чтобы указать ОП в правильном направлении, ожидая более полных ответов. У меня было около 30 свободных минут перед встречей, и я посвятил их SO. Если вам это не нравится, зайдите на сайт с дефисами или что-то в этом роде или создайте себе репутацию вместо того, чтобы жаловаться. - person Fredrik; 25.02.2010


Это делается на уровне языка. Спецификация языка Java очень точно определяет, какая строка дополнение должно сделать.

person Chris Jester-Young    schedule 24.02.2010

String определяется как стандартный тип, как int, double, float и т. д. на уровне компилятора. По сути, все компиляторы имеют перегрузку операторов. Перегрузка операторов не определена для разработчиков (в отличие от C++).

Интересно: этот вопрос был зарегистрирован как ошибка: http://bugs.sun.com/view_bug.do?bug_id=4905919

person Buhake Sindi    schedule 24.02.2010