Почему String неизменяемый? и как это помогает программисту?
Что помимо того что нельзя наследоваться от final класса, а именно String.class , и того что при использовании метода concat() и операции + будет создан новый объект типа String а не изменен существующий, используется при определении неизменяемости класса String ? Как неизменяемость (immutable) класса String помогает в реальных ситуациях программисту. Были бы интересны примеры связанные с HashMap и многопоточностью.
Отслеживать
задан 13 июл 2016 в 10:36
1,996 5 5 золотых знаков 29 29 серебряных знаков 48 48 бронзовых знаков
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Вот тут человек уже ответил на ваш вопрос:
- вы можете передавать строку между потоками и не беспокоиться что она будет изменена
- нет проблем с синхронизацией (не нужно синхронизировать операции со String)
- отсутствие утечек памяти
- в Java строки используются для передачи параметров для авторизации, открытия файлов и т.д. — неизменяемость позволяет избежать проблем с доступом
- возможность кэшировать hash code
А если нужно изменять, есть StringBuffer.
Почему строки в Java неизменные?

Сегодня мы поговорим о строках (Strings) в Java и разберем один очень важный вопрос, которой очень часто задают на собеседованиях, а именно: Почему строки в Java неизменны и финализированы?
Строка является одним из наиболее часто используемых классов в любом языке программирования. Как мы знаем, строка в Java является неизменной и финализированной, а Java Runtime поддерживает общий пулл строк, что делает его этот класс особенным.
Преимущества неизменности строк в Java
- Само существование пула строк возможно только потому, что строка в Java является неизменной. Поэтому Java Runtime экономит много места в общей кучи (java heap space). Дело в том, что различные переменные могут обращаться к одной и той же String-переменной в пуле. Если строка не была бы неизменной, то и интернирование такой строки не было бы возможно. Все потому, что любая переменная могла бы изменять значение этой строки и это сразу бы отражалось и в других переменных.
- Если строка не является неизменной, то это вызывает серьезную угрозу безопасности вашей программы. Например, для соединения с базой данных имя пользователя базы и пароль передаются в виде строк. Тоже самое и в программировании сокетов, где хост и порт передаются в виде обычных String. Именно поэтому значение строки не может быть изменено. В противном случае любой хакер или вредоносная программа может изменить значение строк и вызвать проблемы безопасности в вашей программе.
- Строки неизменны, а это значит, что они потокобезопасны. Это избавляет нас от использования синхронизаций во время работы в мультипоточной среде.
- Строки также используются в загрузчике классов Java и неизменность строк обеспечивает безопасность выполнения загрузки класса. Например, вы пытаетесь загрузить класс java.sql.Connection, но значение ссылки было изменено вредоносной программой. Это может привести к непредвиденным результатам и данным в вашей БД.
- Строки неизменны, а значит их хеш-коды кешируются во время создания и не нуждаются в еще одном вычислении. Это делает строки отличным кандидатом на использование в Map в качестве ключа (key) и будет работать быстрее объектов HashMap.
Вот и все аргументы в пользу неизменности строк в Java. Следите за обновлениями на Javadevblog.com
Неизменность строк в Java
Также известно, что строки (String) в Java являются неизменными (immutable). Это означает, что после создания экземпляра строки его значение нельзя изменить.
Алексей Кодов
Автор статьи
10 июля 2023 в 14:40
Также известно, что строки ( String ) в Java являются неизменными (immutable). Это означает, что после создания экземпляра строки его значение нельзя изменить. Если попытаться что-то изменить, будет создан новый экземпляр строки.
Взгляните на простой пример кода:
String str1 = "Привет, мир!"; String str2 = str1; System.out.println(str1); // выводит "Привет, мир!" System.out.println(str2); // выводит "Привет, мир!" str1 = "Привет, Java!"; System.out.println(str1); // выводит "Привет, Java!" System.out.println(str2); // по-прежнему выводит "Привет, мир!"
В этом коде, даже после изменения str1 , str2 остается без изменений. Это происходит потому, что str1 и str2 изначально указывали на одну и ту же строку «Привет, мир!». Когда str1 был изменен, был создан новый объект строки, и str1 теперь указывает на него, в то время как str2 все еще указывает на старый объект строки.
Но что происходит, если мы попытаемся изменить строку с использованием рефлексии Java? Это возможно, но не рекомендуется. Рефлексия позволяет получить доступ к полям и методам класса во время выполнения, даже если они объявлены как private . Это может привести к непредсказуемым и нежелательным результатам.
String str = "Привет, мир!"; Field field = String.class.getDeclaredField("value"); field.setAccessible(true); char[] value = (char[])field.get(str); value[0] = 'П'; value[1] = 'о'; value[2] = 'к'; value[3] = 'а'; System.out.println(str); // выводит "Пока, мир!"
В этом примере значение строки str было изменено с использованием рефлексии. Это возможно, потому что рефлексия позволяет обойти механизмы безопасности Java. Однако это не рекомендуется, потому что это нарушает принцип неизменности строк и может привести к нежелательным результатам.
Вывод: Строки в Java являются неизменными. Любые попытки изменить строку, даже с использованием рефлексии, могут привести к непредсказуемым и нежелательным результатам.
Как реализована неизменность string в java
В Java строка ( String ) является неизменяемым ( immutable ) объектом, то есть после создания строки её нельзя изменить. Когда мы изменяем строку, мы фактически создаем новую строку, которая содержит изменения. Это означает, что операции над строками в Java обычно более безопасны, чем операции над изменяемыми объектами.
Неизменность строк в Java достигается путем хранения строк в виде массива символов ( char[] ), который является неизменяемым объектом. При изменении строки создается новый массив символов с новым значением строки.
Также Java использует кэширование строк, что позволяет экономить память. Если две строки содержат одинаковые символы, то они ссылаются на один и тот же объект в памяти (строка сохраняется в пуле строк). Это возможно благодаря тому, что строка является неизменяемой.