0Pricing
Java Academy · Урок

Почему строки неизменяемы

Поймите неизменяемость строк

«Почему строки неизменяемы» — бесплатный урок 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 — локальная установка не требуется.

Все уроки этого курса

  1. Почему строки неизменяемы
  2. Создание строк с помощью StringBuilder
  3. Методы StringBuilder
  4. StringBuilder и StringBuffer
← Назад к Java Academy