Почему строки неизменяемы
Поймите неизменяемость строк
«Почему строки неизменяемы» — бесплатный урок Java Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.
Строки неизменяемы
В Java объект String является неизменяемым: после создания его символы уже нельзя изменить. Любой метод, который выглядит как изменение строки, на самом деле возвращает совершенно новую строку.
Методы возвращают новые строки
toUpperCase(), replace() и другие подобные методы не изменяют исходную строку. Они создают новый объект String, оставляя исходный без изменений.
public class Main {
public static void main(String[] args) {
String original = "hello";
String upper = original.toUpperCase();
System.out.println("original: " + original);
System.out.println("upper: " + upper);
}
}Переприсваивание — не изменение объекта
Когда Вы пишете s = s + "!", переменная начинает ссылаться на новую строку. Старый объект строки не изменяется и впоследствии может быть удалён сборщиком мусора.
public class Main {
public static void main(String[] args) {
String s = "hi";
String firstRef = s;
s = s + "!";
System.out.println("s: " + s);
System.out.println("firstRef: " + firstRef);
}
}Зачем нужна неизменяемость
Неизменяемость даёт реальные преимущества:
- Потокобезопасность: строками можно делиться без блокировок
- Кэширование: хеш-коды и элементы пула остаются корректными
- Безопасность: строка, переданная методу, не может быть изменена у Вас за спиной
Пул строк
Одинаковые строковые литералы могут совместно использовать один объект в пуле строк. Это безопасно только потому, что строки никогда не изменяются. Здесь два литерала ссылаются на один и тот же объект из пула.
public class Main {
public static void main(String[] args) {
String a = "java";
String b = "java";
System.out.println(a == b);
System.out.println(a.equals(b));
}
}new String нарушает объединение в пуле
Использование new String(...) принудительно создаёт отдельный объект, поэтому равенство ссылок различается, хотя содержимое совпадает. Всегда сравнивайте содержимое с помощью equals.
public class Main {
public static void main(String[] args) {
String a = "java";
String b = new String("java");
System.out.println("== : " + (a == b));
System.out.println("equals: " + a.equals(b));
}
}Стоимость объединения строк
Каждый оператор + для строк создаёт новый объект. При выполнении в цикле это выделяет много короткоживущих строк, напрасно расходуя время и память.
public class Main {
public static void main(String[] args) {
String result = "";
for (int i = 1; i <= 5; i++) {
result = result + i;
}
System.out.println(result);
}
}Квадратичный рост
Поскольку при каждом объединении копируются все предыдущие символы, построение длинной строки с помощью + в цикле плохо масштабируется (примерно имеет сложность O(n²)). Это основная проблема производительности.
public class Main {
public static void main(String[] args) {
String s = "";
for (int i = 0; i < 1000; i++) {
s += "x";
}
System.out.println("Length: " + s.length());
}
}Неизменяемые значения предсказуемы
Передавать строку в метод безопасно: метод не может изменить Вашу копию. Здесь метод создаёт новую строку, а значение вызывающего кода остаётся неизменным.
public class Main {
static void shout(String s) {
s = s + "!!!";
System.out.println("inside: " + s);
}
public static void main(String[] args) {
String msg = "hello";
shout(msg);
System.out.println("outside: " + msg);
}
}Предварительный обзор решения
Если Вам нужно эффективно строить строки, Java предоставляет StringBuilder — изменяемый вспомогательный класс. Он изменяет содержимое на месте, вместо того чтобы каждый раз выделять новые объекты.
public class Main {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 5; i++) {
sb.append(i);
}
System.out.println(sb.toString());
}
}Сравнение двух подходов
Для нескольких операций объединения + вполне подходит и делает код понятным. Если таких операций много и они выполняются в цикле, предпочитайте StringBuilder. Выбирайте подход в зависимости от объёма построения строки.
public class Main {
public static void main(String[] args) {
String simple = "a" + "b" + "c";
StringBuilder sb = new StringBuilder("a");
sb.append("b").append("c");
System.out.println(simple);
System.out.println(sb);
}
}Быстрая проверка
Что на самом деле происходит, когда Вы вызываете s.toUpperCase() для объекта String?
Повторение
Вы узнали, почему строки неизменяемы:
- Содержимое объекта
Stringникогда не изменяется - Методы возвращают новые строки
- Неизменяемость обеспечивает потокобезопасность, использование пула и безопасность
- Объединение строк с помощью
+в циклах плохо масштабируется StringBuilder— это изменяемое решение
Часто задаваемые вопросы
Урок «Почему строки неизменяемы» бесплатный?
Да — полный текст урока «Почему строки неизменяемы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.
Чему я научусь в уроке «Почему строки неизменяемы»?
Поймите неизменяемость строк Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Java Academy?
Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Почему строки неизменяемы»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Java Academy?
Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Почему строки неизменяемы
- Создание строк с помощью StringBuilder
- Методы StringBuilder
- StringBuilder и StringBuffer