2013-12-05 3 views
4

у меня есть этот код в Java:строк в Java показывает неожиданное поведение

String s0="ab"; 
    String s1="bc"; 
    String s2="abbc"; 
    String s3="ab"+"bc"; 
    String s=s0+s1; 

Когда я пытаюсь сравнить с & s2 с помощью if(s==s2), он возвращает false,
Но сравнивающих s2 & s3 с использованием, if (s2==s3) возвращается true.

Почему выходные данные не одинаковы в обоих случаях?

+5

Я предполагаю, что вы знаете разницу между '.equals()' и '==', когда дело доходит до строк, не так ли? – arshajii

+0

Этот вопрос был дан много ответов на этом сайте. Просто выполните поиск, и вы найдете ответ. – TheEwook

+0

В Java нет специального оператора '==' для строк, он сравнивается только в том случае, если это строка _same_, к которой относятся обе переменные, а не если содержимое одинаковое. –

ответ

7

Строка s3 присваивается compile-time constant, что в точности эквивалентно "abbc". Следовательно, s2==s3 сравнивает два идентичных строковых литерала, которые приводят к true, поскольку эти литералы интернированы.

s0+s1 is не константа времени компиляции, поэтому создается новый объект строки. Поэтому s==s2 возвращает false.


В терминах байт-код,

String s3="ab"+"bc"; 

становится

LDC "abbc" 
ASTORE 1 

Обратите внимание, что "abbc" используется непосредственно.


Наконец, если вы объявите s0 и s1 быть final, то s0+s1бы быть постоянным выражением и s==s2 было бы верно.

+0

Как вы сказали, в случае 's = s0 + s1' будет создан новый объект String. Я согласен, но, наконец,' s' будет ссылаться на тот же строковый объект, который уже существует в String pool.Isn't it? – Suhail

+0

@Suhail No. Если вы создаете новый объект, вы создаете новый объект. Вместо этого ссылается на более старый объект (если нет интернирования, но это не происходит здесь). –

+0

@ DennisMeng Как известно, строковые литералы всегда интернированы. – Suhail

1

Оператор == сравнивает указатели объектов, а не объекты. Чтобы сравнить строковые значения, вы должны использовать либо equals(..), либо equalsIgnoreCase(..), в зависимости от того, что подходит.

Строки s2 и s3, вероятно, сравниваются как равные, поскольку они интернированы за кулисами. Interning использует обычно используемые строки, удерживая их (я думаю) PermGen и просто использую одну ссылку для этой строки. Это полезно, когда у вас много строк с одинаковым значением и работает, потому что строки не изменяются. Всякий раз, когда вы добавляете что-то в строку, создается новая строка.

Смежные вопросы