Строки в Java: равняется по сравнению с == [дубликат]

5
задан Community 23 May 2017 в 12:16
поделиться

7 ответов

Во-первых, String.toString не работает:

/**
 * This object (which is already a string!) is itself returned.
 *
 * @return  the string itself.
 */
public String toString() {
    return this;
}

Во-вторых, строковые константы интернированы, поэтому s1 и s2 за кулисами изменены на один и тот же экземпляр String.

7
ответ дан 18 December 2019 в 05:33
поделиться

s2.toString () возвращает строковое представление. Поскольку это уже строка, она возвращает себя (поэтому сравнение верно).

Все строки размещаются в куче, оператор сравнения просто сравнивает, являются ли они одним и тем же объектом (вот почему s1! = S2).

-2
ответ дан 18 December 2019 в 05:33
поделиться

Учитывая, что == сравнивает ссылки, вы можете видеть из s2 == s3 , что верно, что s2.toString () возвращает s2.

1
ответ дан 18 December 2019 в 05:33
поделиться

При сравнении строк Java вы должны использовать .equals, а не ==.

== Сравнивает ссылки, поэтому s2.ToString () возвращает s2.

Из глоссария java о куче / стеке:

 В JVM Sun интернированные строки (которые включают строковые литералы) являются

хранятся в специальном пуле ОЗУ. называется перманентным генератором, где JVM также загружает классы и магазины код, скомпилированный в собственном коде. Тем не менее интересующие строки ведут себя по-разному чем они хранились в куча обычных объектов.

3
ответ дан 18 December 2019 в 05:33
поделиться

Метод String.intern () может использоваться, чтобы гарантировать, что равные строки имеют равные ссылки. Строковые константы intern ed, поэтому s1 и s2 будут ссылаться на одну и ту же строку. String.toString () просто возвращает себя, то есть a.toString () возвращает a, когда a является строкой. Итак, s2 также == s3.

В общем, строки следует сравнивать не по ссылочному равенству, а по равенству значений, используя equals () . Причина в том, что легко получить две эквивалентные, но разные ссылки. Например, при создании подстрок. Исключением из этого правила является то, что если вы знаете, что обе строки были интернированы заранее (или вы интернировали их как часть сравнения).

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

7
ответ дан 18 December 2019 в 05:33
поделиться

Поскольку String являются неизменяемыми, полезная реализация метода toString - в классе String - возвращать это.

В качестве примера мой rt.jar содержит следующую реализацию:

public String toString() {
return this;
}

Как следствие, ссылка, связанная с s3 , такая же, как ссылка, связанная с s2 .

Учитывая оператор s1 == s2 , это связано с автоматическим вызовом intern () для всех константных строк. Это означает, что во время компиляции код инициализации s2 будет заменен на s2 = s1 , что делает утверждение довольно очевидным, не так ли?

1
ответ дан 18 December 2019 в 05:33
поделиться

Из спецификации виртуальной машины java:

Строковые литералы и, в более общем случае, строки, являющиеся значениями константных выражений, "интернируются", чтобы иметь общие уникальные экземпляры, с помощью метода String.intern.

"andrei" является строковым литералом и поэтому "интернируется". Поэтому обе строки s1и s2 ссылаются на один и тот же объект String, интернированную строку с содержимым "andrei".

Поэтому (s1 == s2) && (s1.equals(s2)) является true. String#toString() не создает новую String (как многие другие методы из String), а просто возвращает this. Поэтому s2 == s3 является true.

3
ответ дан 18 December 2019 в 05:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: