Если вы пришли из С++, то вам будет проще понять, что происходит, если думать о str как о указателе. Вы просто присвоили указателю адрес на другую строку.
LJ>Непонятно, почему не изменился объект Foo::m_Str? Ведь метод Foo::getString() возвращает ссылку, которой я присваиваю новую строку.
LJ>P.S. LJ>А есть разница? LJ>
LJ>private String m_Str = "123"; //Так
LJ>private String m_Str = new String("123"); //И так
LJ>
LJ>Спасибо!
Проще обьяснить так — хотя String и является Object, он передается по значению, а не по ссылке.
Re[2]: Метод возвращает ссылку на объект, а далее...
String a = new String("A");
String b = a; //b указывает на "A"
b = "B"; //b указывает новую строку "B"
LJ>Имеется код: LJ>
LJ>public class TestConsole
LJ>{
LJ> public static void main(String[] args)
LJ> {
LJ> Foo ob = new Foo();
LJ>//в следующей строке получаем указатель на "123"
LJ> String str = ob.getString();
LJ> System.out.println(ob.getString());
LJ>//здесь мы меняем указатель внешней переменной - создаем новый String объект! при этом ob.m_Str указывает на старый объект.
LJ> str = "321";
LJ> System.out.println(ob.getString());
LJ> }
LJ>}
LJ>
P.S.: смотрим в JLS
Здравствуйте, all-x, Вы писали:
AX>Здравствуйте, tantalum, Вы писали:
T>>Проще обьяснить так — хотя String и является Object, он передается по значению, а не по ссылке.
AX>Категорически не верно. Такое объяснение только запутывает. AX>По способу передачи String ничем не отличается от любого другого reference type.
Сорри... жестко стормозил! без внимания прочитал код.
Я имел в виду след. случай
......
...
public static void main(String[] args){
String str = "123";
doSome(str)
System.out.println(str);
}
public void doSome(String str){
str+="456";
}
.....
На экране будет 123, а не 123456.
Re[4]: Метод возвращает ссылку на объект, а далее...
Здравствуйте, tantalum, Вы писали:
T>Здравствуйте, all-x, Вы писали:
AX>>Здравствуйте, tantalum, Вы писали:
T>>>Проще обьяснить так — хотя String и является Object, он передается по значению, а не по ссылке.
AX>>Категорически не верно. Такое объяснение только запутывает. AX>>По способу передачи String ничем не отличается от любого другого reference type.
T>Сорри... жестко стормозил! без внимания прочитал код. T>Я имел в виду след. случай T>...... T>... T>public static void main(String[] args){ T> String str = "123"; T> doSome(str) T> System.out.println(str); T>} T>public void doSome(String str){ T> str+="456"; T>} T>..... T>На экране будет 123, а не 123456.
Здесь имеет значение то, что содержимое объекта класса String изменить нельзя
и операция += записывает параметр метода ссылку на новый объект.
А локальная переменная метода main по-прежнему содержит ссылку на старый объект,
который и печатается. Строки всё равно передаются по ссылке.
Re[4]: Метод возвращает ссылку на объект, а далее...
Здравствуйте, tantalum, Вы писали:
T>>>Проще обьяснить так — хотя String и является Object, он передается по значению, а не по ссылке.
AX>>Категорически не верно. Такое объяснение только запутывает. AX>>По способу передачи String ничем не отличается от любого другого reference type.
T>Я имел в виду след. случай
Здравствуйте, dshe, Вы писали:
D>Здравствуйте, tantalum, Вы писали:
T>>>>Проще обьяснить так — хотя String и является Object, он передается по значению, а не по ссылке.
AX>>>Категорически не верно. Такое объяснение только запутывает. AX>>>По способу передачи String ничем не отличается от любого другого reference type.
T>>Я имел в виду след. случай D>
T>>На экране будет 123, а не 123456.
D>Ну так он здесь тоже не по значению передается, а по ссылке (как и любой другой reference type). А поскольку String immutable, то выражение D>
D>str+="456";
D>
D>на самом деле представляется так: D>
D>str = new StringBuilder().append(str).append("456").toString();
D>
D>т.е. старое значение "123" не изменяется, а заменяется новым "123456".
Пацаны, да что вы мне все разъеснить-то наровите??? Знаю!!! я же написал ПРОЩЕ обьяснить.....!!!!
Re[3]: Метод возвращает ссылку на объект, а далее...
F>>"A String object has a constant (unchanging) value" F>>т.е. присвоение (="321") просто создает новую строку
U>Ну зачем человека путать. Тут дело вовсе не в том, что String какой-то особый- с любым другим объектом другого класса ситуация будет такая-же.
Да нет. В том то и дело, что java.lang.String является немодифицируемым. То есть объект, который создался он уже таким и будет, а при попытке новых присвоений просто создаются новые объекты, выделяется память, получаем на нее ссылку.
Вы же не хотите сказать, что любой класс не может изменять какие-то свои данные? А вот стринг не может. Так что особый.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Метод возвращает ссылку на объект, а далее...
Здравствуйте, RI, Вы писали:
RI>Да нет. В том то и дело, что java.lang.String является немодифицируемым. То есть объект, который создался он уже таким и будет, а при попытке новых присвоений просто создаются новые объекты, выделяется память, получаем на нее ссылку.
RI>Вы же не хотите сказать, что любой класс не может изменять какие-то свои данные? А вот стринг не может. Так что особый.
Тогда любой неизменяемый класс особый, и java.lang.Integer, и java.lang.Character... и свой можно написать, чтобы он был особым в таком смысле.
--
Дмитро
Re[4]: Метод возвращает ссылку на объект, а далее...
RI>Да нет. В том то и дело, что java.lang.String является немодифицируемым. То есть объект, который создался он уже таким и будет, а при попытке новых присвоений просто создаются новые объекты, выделяется память, получаем на нее ссылку.
RI>Вы же не хотите сказать, что любой класс не может изменять какие-то свои данные? А вот стринг не может. Так что особый.
Я хочу сказать, что в данном случае немодифицируемость String никакой роли не играет.
Re[5]: Метод возвращает ссылку на объект, а далее...
Еще одним важным свойством этого класса является неизменяемость. Это означает, что,
породив объект, содержащий некое значение-строку, мы уже не можем изменить это
значение, для этого необходимо создать новый объект.
String s="a";
s="b";
Во второй строке переменная сменила свое значение, но только создав новый объект
класса String.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Метод возвращает ссылку на объект, а далее...
Ok, заменив String на какой-нибудь модифицируемый класс в примере автора топика, что нибудь изменится принципиально? Разве Foo.m_Str изменит свое значение? Будь там хоть String, хоть HashMap, хоть List...
Re[7]: Метод возвращает ссылку на объект, а далее...
Здравствуйте, ukman, Вы писали:
U>Ok, заменив String на какой-нибудь модифицируемый класс в примере автора топика, что нибудь изменится принципиально? Разве Foo.m_Str изменит свое значение? Будь там хоть String, хоть HashMap, хоть List...
Весь прикол в том, что там мы явно вызываем конструктор и все понимают, что создан новый объект.
А тут у автора топика возникал вопрос:
U>А есть разница? U>private String m_Str = "123"; //Так U>private String m_Str = new String("123"); //И так
Вот чтобы не возникало непоняток, я и написал.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Метод возвращает ссылку на объект, а далее...
Может быть, я опять покажусь педантичным, но в цитируемом источнике есть неточности. Во второй строке новый объект не создается. К этому моменту он уже имеется созданный и лежит в пуле строк. А в пул строк он попадает в момент загрузки класса (если его там еще не было). В доказательство справедливости этого можно выполнить такой код
String a, b;
a = "hello";
b = "hello";
System.out.println(a == b);
Если бы всякий раз, когда встречается строковый литерал, создавался бы новый объект, результатом выполнения данного кода был бы вывод false. Тем не менее код выводит true, а это означает, что новый объект не создается.