Нет, не совсем.
Во-первых, есть небольшая разница в семантике. Если a
равно null
, то a.concat(b)
выдает NullPointerException
, но a+=b
будет обрабатывать исходное значение a
, как если бы оно было null
. Кроме того, метод concat()
принимает только значения String
, тогда как оператор +
автоматически преобразует аргумент в строку (используя метод toString()
для объектов). Таким образом, метод concat()
более строг в том, что он принимает.
Чтобы заглянуть под капот, напишите простой класс с a += b;
public class Concat {
String cat(String a, String b) {
a += b;
return a;
}
}
Теперь разберите с помощью javap -c
(входит в Sun JDK). Вы должны увидеть список, включающий:
java.lang.String cat(java.lang.String, java.lang.String);
Code:
0: new #2; //class java/lang/StringBuilder
3: dup
4: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
7: aload_1
8: invokevirtual #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
11: aload_2
12: invokevirtual #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: invokevirtual #5; //Method java/lang/StringBuilder.toString:()Ljava/lang/ String;
18: astore_1
19: aload_1
20: areturn
Итак, a += b
является эквивалентом
a = new StringBuilder()
.append(a)
.append(b)
.toString();
Метод concat
должен быть быстрее. Однако при большем количестве строк метод StringBuilder
выигрывает, по крайней мере, с точки зрения производительности.
Исходный код String
и StringBuilder
(и его базовый класс, частный для пакета) доступен в src.zip Sun JDK. Вы можете видеть, что вы создаете массив символов (изменяя размер по мере необходимости), а затем выбрасываете его, когда создаете окончательный String
. На практике распределение памяти происходит на удивление быстро.
Обновление: Как отмечает Павел Адамски, производительность изменилась в более позднем HotSpot. javac
все еще производит точно такой же код, но компилятор байт-кода обманывает. Простое тестирование полностью терпит неудачу, потому что весь объем кода отбрасывается. Суммирование System.identityHashCode
(не String.hashCode
) показывает, что код StringBuffer
имеет небольшое преимущество. Может быть изменено при выходе следующего обновления или при использовании другой JVM. Из @ lukaseder , списка встроенных функций HotSpot JVM .