Как работают строки Java

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

Я не понимаю, как Java Strings являются "неизменными". В настоящее время у меня есть следующий код:

public static void main(String[] args) {

  String name = "Jacob Perkins";

  System.out.println( name );

  name = name + "!";

  System.out.println( name );

}

Мой вывод следующий:

Jacob Perkins
Jacob Perkins!

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

Ответ 1

Позвольте изображению объяснить это вам:

String example

С левой стороны у вас есть переменная, которая на самом деле является ссылкой.

  • String name = "Jacob Perkins;" Строка "Jacob Perkins" создана, и name указывает на нее.
  • name = name + "!"; Новая строка "Якоб Перкинс!", и ссылка теперь указывает на новую строку. Тем не менее, старый, остается неизменным, потому что String неизменен.

Ответ 2

Сама строка, после ее создания, никогда не может быть изменена. То, что делает ваш образец кода, заключается в замене строки в name на новую строку, созданную из предыдущего содержимого name, и восклицательный знак. (Исходное содержимое name, которое больше не ссылается на какую-либо переменную, в конечном итоге будет извлечено сборщиком мусора.)

Если вы должны были изучить скомпилированный код (или выполнить его с помощью отладчика), вы обнаружите, что выражение name + "!" было скомпилировано в создание объекта StringBuilder и несколько операций над этим объектом.

То есть, строки неизменяемы, но переменная name не является. Его значение изменяется, указывая на разные строки. Строки никогда не меняются.

Ответ 3

Объекты String неизменяемы, только изменения ссылки переменных.

В вашем примере объект "Jacob Perkins" все еще существует и новый объект "Jacob Perkins!" создается.

Переменная name указывает на новый объект.

Ответ 4

Возможно, это поможет вам понять.

Скажем, у вас есть класс Point (java.awt.Point). Скажем, у вас есть один экземпляр p:

Point p = new Point(0,0);

Затем вы создаете новую переменную y, ссылающуюся на тот же объект p, что и:

Point y = p;

Если вы измените значение p, вы также измените y. Поскольку класс Point является изменяемым.

p.setLocation(1,1);

Это делает y ссылкой на местоположение 1,1.

С помощью класса String этого не происходит.

String a = "123";
String b = a;

Если вы делаете a = a + "4"; Новое значение a будет "1234", но b все равно "123";

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

Ответ 5

На самом деле существует 3 созданных объекта String. "Яков Перкинс", "!" и "Яков Перкинс!". Вы действительно не изменили экземпляр "Яков Перкинс". Вы просто изменили ссылку на переменную имени, от экземпляра "Якоб Перкинс" до "Якоба Перкинса!".

Ответ 6

String name = "Jacob Perkins";

String name2 = name + "!";
name.substring(5); // or wather syntax is

Те не меняют имя переменной

Ответ 7

В Java есть ссылки и есть значения.

Когда вы говорите

String foo = "John Smith";

foo - переменная, содержащая ссылку. Ссылка указывает на объект или значение, содержащее "Джон Смит".

Ссылка, содержащаяся в переменной, изменена. Я могу это сделать:

foo = "Jack Smith";

И я перепутал ссылку. Однако, если я пишу код следующим образом:

String foo = "John Smith";
String bar = foo; //bar reference is a copy of foo reference - the same value
foo = "Jack Smith";
System.out.println(bar); //prints John Smith

Мы видим, что, хотя мы изменили foo, bar не изменился. Зачем? Просто, когда мы написали foo = "Jack Smith";, мы сделали foo указателем на новую String. Мы не дошли до foo и не изменили строку, так как Нет метода в Java мутирует или может изменить строку.. Вместо этого возвращается новая строка, а переменная указывается на новую, также неизменяемая строка. Таким образом, объект, который переменная String "указывает", никогда не может быть изменен ничем, кроме этой переменной. Это важное свойство языка Java, которое он гарантирует.