Нет не совсем
Во-первых, есть небольшая разница в семантике. Если 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 .