Re: Метод возвращает ссылку на объект, а далее...
От: zubr Россия  
Дата: 17.08.05 12:41
Оценка: 5 (3)
Здравствуйте, LearnJava, Вы писали:
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
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[6]: Метод возвращает ссылку на объект, а далее...
От: dshe  
Дата: 17.08.05 14:46
Оценка: +2 -1
Здравствуйте, RI, Вы писали:

RI>Здравствуйте, ukman, Вы писали:


U>>Я хочу сказать, что в данном случае немодифицируемость String никакой роли не играет.


RI>Цитирую источник

RI>---------------------
RI>Программирование на Java
RI>Copyright © 2003 Центр Sun технологий МФТИ,ЦОС и ВТ МФТИ®, Все права защищены.
RI>--------------------

RI>Еще одним важным свойством этого класса является неизменяемость. Это означает, что,

RI>породив объект, содержащий некое значение-строку, мы уже не можем изменить это
RI>значение, для этого необходимо создать новый объект.
RI>String s="a";
RI>s="b";
RI>Во второй строке переменная сменила свое значение, но только создав новый объект
RI>класса String.

Может быть, я опять покажусь педантичным, но в цитируемом источнике есть неточности. Во второй строке новый объект не создается. К этому моменту он уже имеется созданный и лежит в пуле строк. А в пул строк он попадает в момент загрузки класса (если его там еще не было). В доказательство справедливости этого можно выполнить такой код
String a, b;
a = "hello";
b = "hello";
System.out.println(a == b);

Если бы всякий раз, когда встречается строковый литерал, создавался бы новый объект, результатом выполнения данного кода был бы вывод false. Тем не менее код выводит true, а это означает, что новый объект не создается.
--
Дмитро
Re: Метод возвращает ссылку на объект, а далее...
От: ukman Россия http://math.welobox.com
Дата: 17.08.05 14:52
Оценка: 4 (2)
Кстати есть небольшая разница в
String s = "123";
и
String s = new String("123");

Например

    String s1 = "123";
    String s2 = "123";
    String s3 = new String("123");
    System.out.println(s1 == s2);
    System.out.println(s1 == s3);


Результат
true
false
Re[4]: Метод возвращает ссылку на объект, а далее...
От: ukman Россия http://math.welobox.com
Дата: 17.08.05 14:00
Оценка: 3 (1) +1
RI>Да нет. В том то и дело, что java.lang.String является немодифицируемым. То есть объект, который создался он уже таким и будет, а при попытке новых присвоений просто создаются новые объекты, выделяется память, получаем на нее ссылку.

RI>Вы же не хотите сказать, что любой класс не может изменять какие-то свои данные? А вот стринг не может. Так что особый.


Я хочу сказать, что в данном случае немодифицируемость String никакой роли не играет.
Re[6]: Метод возвращает ссылку на объект, а далее...
От: ukman Россия http://math.welobox.com
Дата: 17.08.05 14:26
Оценка: 3 (1)
Ok, заменив String на какой-нибудь модифицируемый класс в примере автора топика, что нибудь изменится принципиально? Разве Foo.m_Str изменит свое значение? Будь там хоть String, хоть HashMap, хоть List...
Re[2]: Метод возвращает ссылку на объект, а далее...
От: NorthDragon Россия  
Дата: 18.08.05 06:33
Оценка: 3 (1)
Дело в том что спецификация JVM гарантирует что для всех равных константых строк будет использоваться один и тот же обьект.
Поэтому в первом случае результат сравнения ссылок true.
Во втором же создается новый обьект. в котором как видно из кода содержится либо такой же массив байт.
Либо новый массив с таким же как и у исходной строки содержимым.
Т.е при использовании

String str1 = "bla";
String str2 = "bla";

обьект один, а при использовании


String str1 = "bla";
String str2 = new String(str1);

обьектов два.
впрочем при сравнении их методом equals результат будет true.



   /**
     * Initializes a newly created <code>String</code> object so that it
     * represents the same sequence of characters as the argument; in other
     * words, the newly created string is a copy of the argument string. Unless 
     * an explicit copy of <code>original</code> is needed, use of this 
     * constructor is unnecessary since Strings are immutable. 
     *
     * @param   original   a <code>String</code>.
     */
    public String(String original) {
     this.count = original.count;
     if (original.value.length > this.count) {
         // The array representing the String is bigger than the new
         // String itself.  Perhaps this constructor is being called
         // in order to trim the baggage, so make a copy of the array.
         this.value = new char[this.count];
         System.arraycopy(original.value, original.offset,
                  this.value, 0, this.count);
     } else {
         // The array representing the String is the same
          // size as the String, so no point in making a copy.
         this.value = original.value;
     }
    }
Re[2]: Метод возвращает ссылку на объект, а далее...
От: ukman Россия http://math.welobox.com
Дата: 17.08.05 12:41
Оценка: 1 (1)
T>Проще обьяснить так — хотя String и является Object, он передается по значению, а не по ссылке.

А чем String отличается от Object? Разве в такой же ситуации с другим классом что-то будет по-другому? Все будет также.
Re[4]: Метод возвращает ссылку на объект, а далее...
От: all-x Россия http://treedl.sf.net
Дата: 17.08.05 13:02
Оценка: 1 (1)
Здравствуйте, 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]: Метод возвращает ссылку на объект, а далее...
От: dshe  
Дата: 17.08.05 13:59
Оценка: 1 (1)
Здравствуйте, RI, Вы писали:

RI>Да нет. В том то и дело, что java.lang.String является немодифицируемым. То есть объект, который создался он уже таким и будет, а при попытке новых присвоений просто создаются новые объекты, выделяется память, получаем на нее ссылку.


RI>Вы же не хотите сказать, что любой класс не может изменять какие-то свои данные? А вот стринг не может. Так что особый.


Тогда любой неизменяемый класс особый, и java.lang.Integer, и java.lang.Character... и свой можно написать, чтобы он был особым в таком смысле.
--
Дмитро
Re[7]: Метод возвращает ссылку на объект, а далее...
От: RI Украина  
Дата: 17.08.05 15:08
Оценка: +1
Здравствуйте, dshe, Вы писали:


D>Может быть, я опять покажусь педантичным, но в цитируемом источнике есть неточности. Во второй строке новый объект не создается. К этому моменту он уже имеется созданный и лежит в пуле строк. А в пул строк он попадает в момент загрузки класса (если его там еще не было). В доказательство справедливости этого можно выполнить такой код

D>
D>String a, b;
D>a = "hello";
D>b = "hello";
D>System.out.println(a == b);
D>

D>Если бы всякий раз, когда встречается строковый литерал, создавался бы новый объект, результатом выполнения данного кода был бы вывод false. Тем не менее код выводит true, а это означает, что новый объект не создается.

Все там правильно. Цитирую дальше:
----------------------------------
Поскольку каждый строковый литерал порождает новый объект, что есть очень
ресурсоемкая операция в Java, то зачастую компилятор стремится оптимизировать эту
работу.

Во-первых, если используются несколько литералов с одинаковым значением, то для всех
них будет создан один и тот же объект.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Метод возвращает ссылку на объект, а далее...
От: LearnJava  
Дата: 17.08.05 12:33
Оценка:
Доброго Вам!

Имеется код:
public class TestConsole
{
  public static void main(String[] args)
  {    
    Foo ob = new Foo();
    String str = ob.getString();    
    System.out.println(ob.getString());
    str = "321";
    System.out.println(ob.getString());
  }   
}

class Foo
{
  public String getString()
  {
    return m_Str;
  }
  
  private String m_Str = "123";
}


И соответственно вывод:
123
123

Непонятно, почему не изменился объект Foo::m_Str? Ведь метод Foo::getString() возвращает ссылку, которой я присваиваю новую строку.

P.S.
А есть разница?
private String m_Str = "123"; //Так
private String m_Str = new String("123"); //И так



Спасибо!
Re: Метод возвращает ссылку на объект, а далее...
От: ukman Россия http://math.welobox.com
Дата: 17.08.05 12:35
Оценка:
Если вы пришли из С++, то вам будет проще понять, что происходит, если думать о str как о указателе. Вы просто присвоили указателю адрес на другую строку.
Re: Метод возвращает ссылку на объект, а далее...
От: tantalum Россия  
Дата: 17.08.05 12:38
Оценка:
Здравствуйте, LearnJava, Вы писали:

LJ>Доброго Вам!


LJ>Имеется код:

LJ>
LJ>public class TestConsole
LJ>{
LJ>  public static void main(String[] args)
LJ>  {    
LJ>    Foo ob = new Foo();
LJ>    String str = ob.getString();    
LJ>    System.out.println(ob.getString());
LJ>    str = "321";
LJ>    System.out.println(ob.getString());
LJ>  }   
LJ>}

LJ>class Foo
LJ>{
LJ>  public String getString()
LJ>  {
LJ>    return m_Str;
LJ>  }
  
LJ>  private String m_Str = "123";
LJ>}
LJ>


LJ>И соответственно вывод:

LJ>
LJ>123
LJ>123
LJ>

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]: Метод возвращает ссылку на объект, а далее...
От: all-x Россия http://treedl.sf.net
Дата: 17.08.05 12:41
Оценка:
Здравствуйте, tantalum, Вы писали:

T>Проще обьяснить так — хотя String и является Object, он передается по значению, а не по ссылке.


Категорически не верно. Такое объяснение только запутывает.
По способу передачи String ничем не отличается от любого другого reference type.
Re: Метод возвращает ссылку на объект, а далее...
От: fessa  
Дата: 17.08.05 12:43
Оценка:
Здравствуйте, LearnJava, Вы писали:


"A String object has a constant (unchanging) value"
т.е. присвоение (="321") просто создает новую строку


почитайте Java Language Specifiction — http://java.sun.com/docs/books/jls/

http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.3.3
Re[2]: Метод возвращает ссылку на объект, а далее...
От: ukman Россия http://math.welobox.com
Дата: 17.08.05 12:45
Оценка:
F>"A String object has a constant (unchanging) value"
F>т.е. присвоение (="321") просто создает новую строку

Ну зачем человека путать. Тут дело вовсе не в том, что String какой-то особый- с любым другим объектом другого класса ситуация будет такая-же.
Re[3]: Метод возвращает ссылку на объект, а далее...
От: tantalum Россия  
Дата: 17.08.05 12:56
Оценка:
Здравствуйте, 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]: Метод возвращает ссылку на объект, а далее...
От: dshe  
Дата: 17.08.05 13:11
Оценка:
Здравствуйте, tantalum, Вы писали:

T>>>Проще обьяснить так — хотя String и является Object, он передается по значению, а не по ссылке.


AX>>Категорически не верно. Такое объяснение только запутывает.

AX>>По способу передачи String ничем не отличается от любого другого reference type.

T>Я имел в виду след. случай

T>public void doSome(String str){
T> str+="456";
T>}

T>На экране будет 123, а не 123456.

Ну так он здесь тоже не по значению передается, а по ссылке (как и любой другой reference type). А поскольку String immutable, то выражение
str+="456";


на самом деле представляется так:
str = new StringBuilder().append(str).append("456").toString();

т.е. старое значение "123" не изменяется, а заменяется новым "123456".
--
Дмитро
Re[5]: Метод возвращает ссылку на объект, а далее...
От: tantalum Россия  
Дата: 17.08.05 13:31
Оценка:
Здравствуйте, dshe, Вы писали:

D>Здравствуйте, tantalum, Вы писали:


T>>>>Проще обьяснить так — хотя String и является Object, он передается по значению, а не по ссылке.


AX>>>Категорически не верно. Такое объяснение только запутывает.

AX>>>По способу передачи String ничем не отличается от любого другого reference type.

T>>Я имел в виду след. случай

D>
T>>public void doSome(String str){
T>> str+="456";
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]: Метод возвращает ссылку на объект, а далее...
От: RI Украина  
Дата: 17.08.05 13:35
Оценка:
Здравствуйте, ukman, Вы писали:


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]: Метод возвращает ссылку на объект, а далее...
От: dshe  
Дата: 17.08.05 13:49
Оценка:
Здравствуйте, tantalum, Вы писали:

T>Пацаны, да что вы мне все разъеснить-то наровите??? Знаю!!! я же написал ПРОЩЕ обьяснить.....!!!!


Во-первых, не тебе, а тем, кому это может быть непонятно, а во-вторых, нечего было людей путать.
--
Дмитро
Re[5]: Метод возвращает ссылку на объект, а далее...
От: RI Украина  
Дата: 17.08.05 14:23
Оценка:
Здравствуйте, ukman, Вы писали:

U>Я хочу сказать, что в данном случае немодифицируемость String никакой роли не играет.


Цитирую источник
---------------------
Программирование на Java
Copyright © 2003 Центр Sun технологий МФТИ,ЦОС и ВТ МФТИ®, Все права защищены.
--------------------

Еще одним важным свойством этого класса является неизменяемость. Это означает, что,
породив объект, содержащий некое значение-строку, мы уже не можем изменить это
значение, для этого необходимо создать новый объект.
String s="a";
s="b";
Во второй строке переменная сменила свое значение, но только создав новый объект
класса String.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Метод возвращает ссылку на объект, а далее...
От: RI Украина  
Дата: 17.08.05 14:40
Оценка:
Здравствуйте, 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[2]: Метод возвращает ссылку на объект, а далее...
От: Petrovich_Alex  
Дата: 17.08.05 15:47
Оценка:
Здравствуйте, zubr, Вы писали:

Z>Здравствуйте, LearnJava, Вы писали:

Z>
Z>String a = new String("A");
Z>String b = a; //b указывает на "A"
Z>b = "B"; //b указывает новую строку "B"
Z>


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>>

Z>P.S.: смотрим в JLS

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

P.S.: смотрим в JLS
... << RSDN@Home 1.1.4 stable rev. 510>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.