оператор присваивания Строковый объект

Я новичок в программировании на JAVA. Я прочитал это в своей книге

String a="Hello";
String b="Hello";
System.out.println(a==b);

Это должно вернуть false, поскольку a и b относятся к разным экземплярам объектов String.

Потому что оператор присваивания сравнивает экземпляры объектов, но тем не менее я получаю true.
Я использую Eclipse IDE.

Пример в книге выглядит следующим образом:

String s = "s";
String sToo = "s";
System.out.println(a == b);
System.out.println(s == sToo);

Этот фрагмент кода выводит «false» для s == sToo. Это потому, что s и sToo являются ссылками на разные экземпляры объекта String. Таким образом, несмотря на то, что они имеют одинаковое значение, они не равны в глазах операторов равенства. Кроме того, s == «s» выводит false, потому что строковый литерал создает еще один экземпляр класса String.

Название книги: JAVA 7 для начинающих.


person chetan mehta    schedule 06.10.2013    source источник
comment
Нет, значения a и b относятся к одному и тому же объекту из-за интернирования строк. Вы уверены, что в книге приводится точный пример? Также обратите внимание, что оператор присваивания вообще не выполняет сравнение. Оператор присваивания — =; возможно, вы имели в виду оператор равенства ==?   -  person Jon Skeet    schedule 06.10.2013
comment
Чтобы увидеть, как он может возвращать false, попробуйте String a=new String("Hello"); String b = "Hello";   -  person Flavio    schedule 06.10.2013
comment
Извините, действительно сделал тип. Думал об операторе присваивания. Очень жаль   -  person chetan mehta    schedule 06.10.2013
comment
Если это действительно то, о чем говорится в книге, то прочтите другую книгу.   -  person JB Nizet    schedule 06.10.2013
comment
@JonSkeet, я думал об операторе сравнения   -  person chetan mehta    schedule 06.10.2013


Ответы (1)


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

«Все литеральные строки и константные выражения со строковым значением интернированы».

Обратите внимание, что это относится только к строкам, которые определены во время компиляции, поэтому следующее действительно будет печатать false.

String a="Hello";
String b=new String("Hello");
System.out.println(a==b); //prints false because a new string was forced

or

String a="Hello";
String b1="He";
String b2="llo";
String b=b1+b2;

System.out.println(a==b); //prints false because b wasn't know to be "Hello" at compile time so could not use string pooling

Н.Б. Можно заставить второй фрагмент печатать true, сделав b1 и b2 окончательными, позволяя b1+b2 быть известным во время компиляции. В целом вам нужно быть очень осторожным и относиться к string==string с большим уважением, в подавляющем большинстве случаев вы хотите, чтобы string.equals(string) не существовало.

person Richard Tingle    schedule 06.10.2013
comment
Книга (а) не знает, о чем она говорит, или (б) была написана до того, как эта оптимизация была включена в java, вы можете только надеяться, что она (б) - person Richard Tingle; 06.10.2013
comment
книга была опубликована в 2012 году издательством Apress. так что я думаю, что это новый .Может отсутствовать в этот момент. - person chetan mehta; 06.10.2013
comment
да, это действительно печатает правду. - person chetan mehta; 06.10.2013
comment
@JB Nizet Последний вопрос: String a= ведет себя как примитив, а String a=new String() делает объект String. Это ЭТО??? - person chetan mehta; 06.10.2013
comment
@chetanmehta Нет, оба являются объектами, однако компилятор пытается быть умным и объединяет их в несколько ссылок, каждая из которых указывает на один и тот же объект, хотя во время компиляции известно, что они одинаковы. - person Richard Tingle; 06.10.2013
comment
Интернируются не только строковые литералы, но и любое константное выражение String времени компиляции. Например, в вашем последнем примере объявление b1 и b2 переменными final сделает b1+b2 константным выражением времени компиляции. - person Ted Hopp; 06.10.2013
comment
Почти достаточно для +1, но N.B. следует читать, чтобы второй фрагмент вывел true . . .. Кроме того, я предпочел бы видеть документы цитируются: Все литеральные строки и константные выражения со строковым значением интернируются. - person Ted Hopp; 06.10.2013
comment
@TedHopp Спасибо за вашу помощь, я должен признать, что многому научился, отвечая на этот вопрос, помимо моего первоначального упрощенного понимания (что на самом деле не идея, а эй-хо) - person Richard Tingle; 06.10.2013