Почему строка считается неизменяемой?В чем преимущества такого дизайна?
1. Неизменность строки
Строка имеет тип final, и конечный класс не может быть унаследован.
Строка неизменяема. При изменении значения существующей строки (например, изменении str на “abcdef”) данные исходного адреса памяти не изменяются, а перенаправляется исходная ссылка на новый объект и новый адрес.Почему она неизменна?
(JDK 1.8),java.язык. Первые несколько поведений класса String:
public final class String
implements java.io.Serializable, Comparable, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
...
...
}
Строка по сути представляет собой массив символов, хранящийся со значением переменной-члена[].Значение переменной-члена[] украшено ключевым словом final, что означает, что ссылочный адрес остается неизменным после создания поля; разрешение на доступ является закрытым, что означает, что к нему нельзя получить доступ извне, и то же самое верно для хэша переменной-члена.кроме того Строка не предоставляет внешних методов для изменения этих двух частных свойств.
Сам класс String объявлен как окончательный и не может быть унаследован, то есть ограничение нельзя обойти расширением.
Другой момент заключается в том, что при создании объекта переменные-члены инициализируются с помощью глубокого копирования вместо прямого копирования, чтобы предотвратить изменение входного объекта.Например, когда значение массива переменных[] передается для инициализации:
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
2. Причины и преимущества этого дизайна:
На самом деле, причина в преимуществах. String разработана так, чтобы быть неизменной, главным образом с точки зрения производительности и безопасности.
1. Пул строковых констант
Пул строковых констант (пул строк) в Java существует для оптимизации производительности.
Пул строковых констант – это специальная область хранения в кучной памяти Java.При создании строкового объекта он сначала будет искать в пуле строковых констант. Если он будет найден, ссылка на строку будет возвращена напрямую. Новый объект не будет создан.Это может уменьшить нагрузку на память виртуальных машин и повысить производительность.Например, следующий код:
String str1 = "abc"; String str2 = "abc";
В это время ссылки str1 и str2 указывают на один и тот же объект “abc” в пуле констант, как показано на рисунке ниже.:
Если String является изменяемым классом, то модификация объекта String путем ссылки на str1 напрямую приведет к тому, что ссылка на str2 получит неверное значение.Следовательно, если строка изменчива, то пул строковых констант не имеет смысла существовать.
2. 缓存 Хэш-код
Хэш-код строки (хэш-код) часто используется в Java.В классе String есть следующий код:
/** Cache the hash code for the string */ private int hash;
Видно, что хэш-код строкового объекта хранится в переменной-члене hash.Поскольку класс String является неизменяемым, после создания объекта значение хэша сохраняется в кэше и не может быть изменено.Каждый раз, когда хэш-код объекта используется в будущем, его нет необходимости пересчитывать, и он может быть возвращен напрямую.Это делает строку очень подходящей в качестве хэш-карты В ключе значительно повышается эффективность.
3. Безопасность многопоточности
При многопоточности значение типа переменной, скорее всего, будет изменено в других потоках, что приведет к непредвиденным последствиям.Неизменяемая строка может свободно использоваться несколькими потоками без какой-либо обработки синхронизации.
В целом, неизменность класса String – это хорошо продуманный дизайн.
Оригинал: “https://dev.to/deecyn/string-34fe”