2015-09-15 2 views
-2

Отредактировано: Я тестировал этот код в Java и печатная продукция была «истинной», в то время как компилятор сравнивает ссылки, а не значение строк, почему это «правда»?Java проверка равенство для струнного

public class Main {  
    public static void main(String[] args) {   
     String s1 = "string"; 
     String s2 = "string"; 
     System.out.println(""+(s1==s2)); 
    } 
} 
+1

java 7 также напечатает 'true' – Rustam

+0

@a_horse_with_no_name Может играть с постоянным пулом :) –

+0

Была ли ваша Java 6 JRE из Sun/Oracle или альтернативной JRE? – RealSkeptic

ответ

3

правила Строка равенства не изменились в Java 8 и s1==s2 принтами всегда true в этом случае, так как они указывают на один и тот же ячейку памяти в постоянном пуле, которые обычно находятся на динамической памяти.

Я только что проверил Java6, и это правда.

+0

Хорошо, спасибо. Я был неправ. Я заменил выражение «System.out.println (« "+ (s1 == s2)); с этими двумя утверждениями, и результат был «ложным». Благодарю. Строка s3 = "stringstring"; System.out.println ("" + (s3 == s1 + s2)); – Mansour

+0

@Mansur Ответ после редактирования вопроса: потому что оба указывают на одинаковое расположение памяти в постоянном пуле. –

1

Не было изменений, оператор == проверяет, указывают ли две ссылки на один и тот же объект. Строковые литералы помещаются в пул строк. Поэтому «строка» помещается в пул строк, s1 и s2 указывают на это, следовательно, вывод истины.

+0

Спасибо, ты прав. – Mansour

0

Это зависит от компилятора, чтобы решить, в данном случае, s1 == s2. Условие проверяет, являются ли s1 и s2 одним и тем же объектом. Это, вероятно, будет правдой, поскольку разумный компилятор будет иметь постоянный пул, но не обязательно так.

Однако ваше намерение сравнивает строки, а не объекты, поэтому equals() - правильный метод, и использование == для этого неверно.

+5

Никакие компиляторы не будут поддерживать постоянный пул. JVM делает. –

1

В вашем отредактированном вопросе вы определили два Строковые литералы. Согласно JLS § 3.10.5 этим литералам интернированы:

строковые всегда относится к одному экземпляру класса String. Это связано с тем, что строковые литералы, или, в более общем смысле, строки, которые являются значениями константных выражений (§15.28), «интернированы», чтобы обмениваться уникальными экземплярами, используя метод String.intern.

Поэтому ссылаться на равенство с использованием == всегда будет возвращать true для s1 == s2 где:

String s1 = "string"; 
String s2 = "string"; 

Состояния JLS (почти точно) то же самое для Java 7 и Java 6

Примечание хотя, что есть некоторые тонкие различия в том, как интернирование строк работает между определенными версиями JDK. См., Например, "intern() behaving differently in Java 6 and Java 7"

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