← Назад к вопросам

В чём разница между String, StringBuilder и StringBuffer?

2.0 Middle🔥 131 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

В чём разница между String, StringBuilder и StringBuffer?

Эти три класса предназначены для работы со строками в Java, но имеют принципиально разные характеристики. Понимание их различий критически важно для производительности приложения.

String — неизменяемость как фундамент

String — это неизменяемый класс. Когда вы создаёте строку, её значение не может быть изменено:

String str = "Hello";
str = str + " World";  // создаётся новая строка, старая остаётся в памяти

При каждом изменении создаётся новый объект String. Это имеет важные последствия:

  • Безопасность потоков: String автоматически thread-safe, так как не может измениться после создания
  • Использование памяти: при частых операций конкатенации образуется много "мусора"
  • Хеширование: неизменяемость позволяет кешировать хеш-код
String str1 = "Hello";
String str2 = "Hello";
system.out.println(str1 == str2);  // true — используется String pool

StringBuilder — производительность без синхронизации

StringBuilder — это изменяемый класс, оптимизированный для производительности:

StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
String result = sb.toString();  // "Hello World"

Ключевые характеристики:

  • Отсутствие синхронизации: методы не синхронизированы, что делает его быстрым
  • Мутирующий: изменяет свой внутренний буфер вместо создания новых объектов
  • Производительность: в циклах работает в 10-100 раз быстрее, чем конкатенация String
// Плохо — создаёт 1000 объектов String
String result = "";
for (int i = 0; i < 1000; i++) {
    result += i;  // O(n²) сложность!
}

// Хорошо — создаёт 1 объект StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);  // O(n) сложность
}
String result = sb.toString();

StringBuffer — безопасность в многопоточности

StringBuffer похож на StringBuilder, но все его методы синхронизированы:

StringBuffer buffer = new StringBuffer();
buffer.append("Hello");  // синхронизированный метод
buffer.append(" World");
String result = buffer.toString();

Характеристики:

  • Синхронизация: потокобезопасен, может использоваться в многопоточной среде
  • Производительность: медленнее StringBuilder из-за overhead синхронизации
  • Редкое применение: в современной Java используется редко

Сравнительная таблица

ХарактеристикаStringStringBuilderStringBuffer
ИзменяемостьНетДаДа
ПотокобезопасностьДаНетДа
ПроизводительностьНизкая при измененияхВысокаяСредняя (медленнее, чем StringBuilder)
Использование памятиНеэффективноЭффективноЭффективно
ПрименениеОбщие случаиЦиклы, сложениеРедко (старая Java)

Практические примеры

Когда использовать String:

// Когда значение не меняется
final String API_KEY = "secret-key";
String userName = "John";
String message = "User: " + userName;  // одна конкатенация

Когда использовать StringBuilder:

// В циклах и при сложении
StringBuilder query = new StringBuilder();
query.append("SELECT * FROM users WHERE ");
for (String condition : conditions) {
    query.append(condition).append(" AND ");
}

// При обработке больших объёмов
StringBuilder json = new StringBuilder();
for (DataItem item : items) {
    json.append("{..}");
}

StringBuffer — практически не используется:

// Если действительно нужна синхронизация (очень редко)
public synchronized StringBuffer buildThreadSafeString() {
    StringBuffer buffer = new StringBuffer();
    buffer.append("value");
    return buffer;
}
// Но обычно достаточно создать StringBuilder в synchronized методе

Автоматическая оптимизация компилятором

С Java 9+ компилятор автоматически преобразует конкатенацию String в StringBuilder:

String result = "Hello" + " " + "World";
// Компилятор преобразует в эквивалент:
// StringBuilder sb = new StringBuilder();
// sb.append("Hello").append(" ").append("World");
// String result = sb.toString();

Резюме

  • String — для константных, не изменяемых значений
  • StringBuilder — для изменяемых строк, особенно в циклах (стандартный выбор)
  • StringBuffer — исторический класс, избегайте в новом коде
В чём разница между String, StringBuilder и StringBuffer? | PrepBro