Почему строка не изменяется при изменении элемента массива строк - PullRequest
2 голосов
/ 01 июля 2019

Я не могу понять, почему строка не работает так, как объект, поэтому при ее изменении меняется и переменная, которой она назначена.

Я попытался создать массив строк, а затем присвоил ссылку на один элемент переменной (я говорю, что ссылка, поскольку, как я понимаю, Java передается по значению, а ссылка на память - это "значение")
Когда я изменил элемент String, переменная не отражает изменения.

String[] arr={"abc","def"};

String s=arr[1];

arr[1]+="123r";

for (String i:arr) {System.out.print(i);}

System.out.println(); // prints "abcdef123r"

System.out.println(s); //prints "def"

Возможно, из того, что я читал, оператор присваивания не работает так для строк.

Ответы [ 3 ]

6 голосов
/ 01 июля 2019

Строки неизменны.Это означает, что их ценность никогда не меняется.Их ссылки могут быть переназначены, что и происходит здесь.

Временная шкала в комментариях:

// Create two Strings. [string1]="abc", [string2]="def"
// Assign [string1] to arr[0]. 
// Assign [string2] to arr[1].
String[] arr={"abc","def"};

// Get value from arr[1] = [string2]
// Assign [string2] to s
String s=arr[1];

// Get value from arr[1] = [string2]
// create [string3] = "123r"
// create [string4] = [string2] + [string3]
// assign [string4] to arr[1]
arr[1]+="123r";

// get value from arr[0] = [string1]
// print [string1] = "abc"
// get value from arr[1] = [string4]
// print [string4] = "def123r"

for (String i:arr) {System.out.print(i);}

System.out.println(); // prints "abcdef123r"

// get value from s = [string2]
// print value "def"
System.out.println(s); //prints "def"

Я говорю "ссылка", поскольку из того, что я понимаю, Java передается по значению иссылка на память - это «значение»

Почти правильно.
Ссылка - это адрес.Значение можно найти в памяти по этому адресу.

Итак, что у вас есть:
Переменная = удобочитаемая.яблоко.
ссылка = адрес памяти.Считываемое компьютером.
значение = несколько байтов в памяти по заданному адресу.

Поэтому, когда вы делаете

 String s = arr[1];

Вы назначаете адрес памяти, который был связан с переменной arr[1] к переменной s.Значение в ОЗУ остается неизменным и не изменяется.

Когда вы делаете

 arr[1] += "123r";

Вы создаете целую новую строку.
Расширенное это то, что происходит шаг за шагом.

arr[1] += "123r";
arr[1] = arr[1] + "123r"; 
arr[1] = "def" + "123r";
arr[1] = "def123r";

Таким образом, arr[1] присваивается адрес памяти / ссылка на результат операции после =
Это действие, однако, не имеет никакого отношения к переменной s, так как эта переменнаясодержит адрес исходной строки, и нет кода для обновления этого адреса ссылки / памяти.

1 голос
/ 01 июля 2019

Короче говоря, ожидаемое вами поведение.В Java строки рассчитаны на неизменяемость, то есть их значения НЕ МОГУТ изменяться.

Что означает неизменяемость строк?

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

 String s = "Stack";  
 s.concat(" overflow"); 
 System.out.println(s);

Что вы ожидаете получить? Переполнение стека верно?НЕТУ!вывод Стек .Вы можете проверить и убедиться сами.

Именно так ведет себя строка.

Конечно, мы можем изменить приведенную выше кодовую базу, чтобы она работала так, как мы хотим, выполнив следующее:

 String s = "Stack";  
 s = s.concat(" overflow"); 
 System.out.println(s);

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

Надеюсь, это поможет.Веселого кодирования!Под редакцией

1 голос
/ 01 июля 2019

мы знаем, что строка является константной переменной в Java.

  1. String[] arr={"abc","def"}

    пул строковых переменных const: «abc», «def»

    обр [0] -> "abc"

    обр [1] -> "def"

  2. String s=arr[1]

    пул строковых переменных const: «abc», «def»

    обр [0] -> "abc"

    обр [1] -> "def"

    с -> "def"

  3. arr[1]+="123r"

    пул строковых переменных const: «abc», «def», «def123r», «123r»

    обр [0] -> "abc"

    обр [1] -> "def123r"

    s -> "def"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...