В Java класс String — immutable (неизменяемый): при любой операции изменения создаётся новый объект. Классы StringBuilder и StringBuffer — изменяемые, используются для конкатенаций внутри циклов и сложных преобразований.
Ключевые различия:
String: immutable, thread-safe без дополнительной синхронизации. Идеален для читабельного, неизменного текста (например, ключи, сообщения).StringBuilder: mutable, не thread-safe, но быстрая конкатенация. Применяется там, где строки изменяются много раз.StringBuffer: mutable, thread-safe (методы синхронизированы), но уступает в производительности StringBuilder.Пример сравнения скорости:
String s = ""; for (int i = 0; i < 10000; i++) { s += i; // создаёт каждый раз новый String, медленно! } // Лучше так: StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10000; i++) { sb.append(i); } String result = sb.toString();
Подводные камни:
String.intern() может вызывать OutOfMemoryError в PermGen/Metaspace при большом количестве уникальных строк.Вопрос: "Является ли конкатенация строк с помощью оператора "+" внутри цикла эффективной?"
Ответ: Нет, каждый раз создаётся новый String-объект, что сильно загружает память и GC. Для множества операций лучше использовать StringBuilder или StringBuffer (если требуется потокобезопасность).
Пример:
String s = ""; for (int i = 0; i < 1000; i++) { s += i; // ОЧЕНЬ неэффективно! } // vs StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1000; i++) { sb.append(i); }
История
В банковском проекте конкатенация строк с помощью оператора "+" в большом цикле замедлила nightly-аналитику в 15 раз. Проблему решили заменой на StringBuilder, время выполнения сократилось с 40 минут до 2.
История
Молодой разработчик ошибся с потоками и использовал StringBuilder в одном и том же объекте-фасаде, к которому одновременно обращались несколько потоков. Это привело к случайным глюкам и неверным результатам из-за отсутствия синхронизации.
История
На проекте создавались уникальные метки с помощью String.intern(). При росте пользователей до десятков миллионов JVM стала выбрасывать OutOfMemoryError: PermGen space. Решили отказом от использования intern() и переходом на другие механизмы кеширования.