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

Строки Java по умолчанию неизменяемы. Неизменяемость строк помогает в предоставлении таких функций, как кэширование, безопасность, высокая производительность и лучшее использование памяти. В этом руководстве обсуждается, как неизменяемость строк помогает в достижении этих функций.

1. Что такое неизменяемый класс?

Начнем с самой неизменяемости. Неизменяемый объект — это объект, состояние которого гарантированно останется неизменным в течение всего срока его существования. Это означает, что состояние объекта, однажды инициализированное, никогда не может быть изменено.

В Java также есть неизменяемые классы, которые в основном являются String и классами-оболочками. Узнайте больше о том, как создать неизменяемый класс.

2. Строки хранятся в пуле строковых констант.

Память в Java делится на три части: куча, стек и строковый пул. Строковый константный пул — это специальная область, используемая для хранения строковых литералов.

Когда мы создаем String, в пуле строк ищется объект String с точно таким же содержимым. Если найден существующий объект String, то его ссылка указывает на новую переменную, таким образом, по сути, существующий объект также повторно используется для объявления новой строки. Это помогает минимизировать использование памяти из-за нескольких строк с одинаковым содержимым.

String str1 = "value";String str2 = "value";String str3 = "value";

Вышеприведенная программа создает 3 переменные типа String, все из которых указывают на один и тот же объект в области пула Spring. Все будущие String с содержимым «value» будут указывать на один и тот же объект в куче и, таким образом, экономить память.

Почему строки в Java неизменяемы?0

Когда мы изменяем строку, в пуле создается новая строка с измененным содержимым. Существующий объект никогда не изменяется.

str3 = "test";
Почему строки в Java неизменяемы?1

Если в пуле нет ссылочной переменной, указывающей на строковый объект, объект удаляется сборщиком мусора. Таким образом, строка, однажды созданная, никогда не изменяется.

3. Преимущества неизменяемых строк

Давайте теперь разберемся, как обсуждаемая выше неизменность помогает во время выполнения.

3.1 Безопасность приложений и данных

Первая и, несомненно, самая важная причина — это безопасность. Ну, это касается не только нашего приложения, но и самого JDK. Механизм загрузки классов Java работает с именами классов, переданными в качестве параметров, затем эти классы ищутся в classpath.

В следующей программе мы загружаем драйвер сервера SQL по имени его класса. Представьте на мгновение, что строки были бы изменяемыми, тогда злоумышленник мог бы изменить имя драйвера, загрузить плохой класс драйвера во время выполнения и, приложив совсем немного усилий, взломать приложение.

public static final String DRIVER_CLASS = "com.microsoft.sqlserver.jdbc.SQLServerDriver";Class.forName(DRIVER_CLASS);

Аналогично, злоумышленники могут изменять операторы SQL и выполнять SQL-инъекции во время выполнения. Неизменяемость гарантирует, что такие изменения никогда не произойдут.

3.2 Улучшенная производительность

Неизменяемость класса String дает основу пула строк. Без неизменяемости нет никакой разницы между обычной кучей памяти и пулом строк.

Как обсуждалось в предыдущем разделе, пулы строк помогают добиться более эффективного использования памяти и, следовательно, более высокой производительности.

3.3 Безопасность потока

Неизменяемые объекты автоматически потокобезопасны в многопоточных приложениях. Если что-то нельзя изменить, то даже поток не может это изменить. Простая вещь!

Поскольку класс String является основным строительным блоком языка программирования Java, из-за его использования в механизме загрузки классов, необходимо предотвратить грязный класс String в случае нескольких потоков. Неизменяемость здесь творит чудеса.

3.4 Кэширование

Кэши обычно реализуются как пары ключ-значение, аналогично реализации Map в Java. Ключи кэша обычно хранятся как строки для быстрого поиска.

Подумайте, можем ли мы изменить ключ после того, как его связанное значение сохранено в кэше. После этого не будет возможности получить значение, пока мы случайно не создадим тот же ключ.

Неизменяемость строк гарантирует, что ключи кэша никогда не изменятся. Вот почему строки являются наиболее используемыми ключами в кэшах и картах в Java.

4. Заключение

Из вышеизложенного можно сделать вывод, что неизменность строк помогает достичь требуемой безопасности и производительности в приложении Java.

Прокрутить вверх