Путаница по поводу неизменности и финала в Java

В моих попытках подготовиться к техническим интервью по Core Java было несколько популярных вопросов, которые были отмечены как «самые сложные» и на которые многие блоггеры затруднялись ответить. Почему «Java является неизменной или окончательной?» — одна из них. У нас уже есть хороший набор статей, написанных на эту тему. Поэтому я не собираюсь изобретать инструмент. Но решил добавить свои взгляды на некоторые заблуждения, через которые прошли люди, пытаясь понять и объяснить это.

Сначала я отвечу на этот вопрос в соответствии с моим пониманием этого, так что мне будет намного легче объяснить заблуждение, которое стоит за этим вопросом. Immutable и final — это две разные концепции, используемые в Java. Даже если вы назвали причину, по которой String является неизменной, вашего ответа недостаточно, чтобы доказать, почему String стала окончательной.

Неизменяемый — означает, что содержимое объекта НЕ может быть изменено или модифицировано любой ценой.

Например, String s = new String («ABC»); — создает объект String в памяти.

Когда вы пытаетесь изменить это значение, добавив строку ниже

s= «abc»; — создает новый объект со значением «abc» в памяти, а наша объектная переменная «s» первого созданного объекта («ABC») теперь указывает на этот новый создан объект 'abc'. Таким образом, в конечном итоге переменная «s» указывает на объект «abc». Но объект «ABC» по-прежнему остается в памяти без объектной переменной. Эта методология имеет место с неизменным качеством строкового класса. После того, как строковому объекту присвоено значение, это значение нельзя изменить. Это называется неизменностью.

final — ключевое слово, которое имеет разные значения в зависимости от используемого контекста.

  1. Переменные — чтобы предотвратить изменение ссылки на переменную, чтобы она указывала на другую ссылку или значение (это НЕ означает, что «конечные» переменные не могут быть изменены. Их можно изменить с помощью метода установки)
  2. Методы — для предотвращения переопределения.
  3. Классы — чтобы предотвратить продление.

Таким образом, с приведенными выше объяснениями, если вы посмотрите на наш вопрос, да, строка является неизменяемой, и наиболее подходящим рассуждением является то, что строковые объекты создаются в постоянном пуле кучи String. Пул строковых констант улавливает эти объекты, и они находятся в памяти (пул строковых констант), пока не будут уничтожены сборщиком мусора. Это необходимо в соответствии с потребностью Java в управлении памятью (если был другой запрос на создание другого объекта с теми же значениями, эти кэшированные объекты ссылаются на новую ссылку на переменную). Поскольку String — это особый класс Java, в одной программе могут быть тысячи объектов этого класса. Поэтому для управления памятью методология перехвата объектов String с помощью концепций пула констант String была обязательной. Чтобы сделать однажды созданные объекты постоянными, String должна быть неизменяемой. Тогда только объект может оставаться с тем же значением внутри, пока объект не будет уничтожен. (Обратите внимание, что существует и другой набор причин неизменяемости строк. См. https://javarevisited.blogspot.com/2010/10/why-string-is-immutable-or-final-in-java.html) для некоторых других ценных советов.

Тогда почему String является final? Здесь термин final относится к классу String. Если вы посмотрите на реализацию класса String, вы увидите, что он был объявлен как окончательный класс. Потому что разработчики Java не хотели, чтобы кто-либо из пользователей расширял этот класс String и переопределял его поведение.

Итак, вкратце, сделав класс String Immutable, разработчики Java достигли своей цели управления памятью, позволив константному пулу String перехватывать строковые объекты. Более того, они хотели сохранить это поведение (неизменяемость) класса String, поэтому они сделали класс String окончательным.

Примечание. Инициализация строковой переменной и создание объекта с ключевым словом final — это отдельная история.

Например. final String s1= new String("ABC"); — этот конечный относится к ссылке на переменную строковых объектов. (имеется в виду — эта переменная не может ссылаться на какое-либо другое значение или ссылку на переменную). Теперь, если мы сделаем что-то вроде того, что указано ниже, это даст ошибку компиляции.

s1= «ghy»Последняя локальная переменная s1 не может быть назначена. Оно должно быть пустым и не использовать составное присвоение