путаница с результатами Java String - PullRequest
4 голосов
/ 11 июля 2011
class Test{
       public static void main(String s[]){
              String s1="welcome",s2="come";        
              System.out.println(s1==("wel"+"come"));    //prints : true
              System.out.println(s1==("wel"+s2));        //prints : false
      }
}

Я хочу знать, почему оба метода println дают разные результаты. Пожалуйста, объясните подробно.

Ответы [ 9 ]

7 голосов
/ 11 июля 2011

== всегда сравнивает сами ссылки.

В первом сравнении константное строковое выражение "wel" + "come" оценивается в время компиляции , и в результате вы получаете ту же внутреннюю ссылку, что и для литерала, используемого для инициализации s1.

Во втором случае конкатенация выполняется во время выполнения, создавая новую строку.

Чтобы сравнить две строки для равенства содержимого (вместо проверки, ссылаются ли две ссылки на один и тот же объект), используйте equals:

System.out.println(s1.equals("wel" + "come"));
System.out.println(s1.equals("wel" + s2));
2 голосов
/ 11 июля 2011
String s1="welcome",s2="come";        
System.out.println(s1==("wel"+"come"));    //prints : true

Это константы времени компиляции, поэтому компилятор может встроить код в

System.out.println(s1==("welcome"));    //prints : true

Здесь вторая часть не является константой времени компиляции, поэтому компилятор не может оптимизироватьследовательно, новый объект String создается во время выполнения:

System.out.println(s1==("wel"+s2));        //prints : false
0 голосов
/ 11 июля 2011

Дело в том, что в Java строки могут рассматриваться как объект или как примитивный тип.

как примитивный тип:

String text1 = "a";

как объект:

String text2 = new String("a");

но в java == всегда сравнивает ссылки, а не значения.

когда я пишу этот код:

text1 == text2 возвращает false, теперь text2 + "b" == "ab" также возвращает false

, поскольку он сравнивает созданный во время выполнения объект с константой, и это то, что относится к вашему второму случаю, в первом случае "wel" + "come" будет рассматриваться как "welcome "java-компилятором и как константа, это то же самое, что и константа, с которой вы определили строковую переменную.

0 голосов
/ 11 июля 2011

В Java нет перегрузки операторов, как в C ++ и C #.Таким образом, это означает, что оператор == всегда сравнивает ссылки.И сравниваемые строки могут быть одинаковыми, но они имеют разные ссылки.Что вызывает false.

Но почему был истинный результат?Ну, Java создает пул строк.Все строковые литералы будут помещены в пул строк во время компиляции.Это означает, что:

String literalString1 = "foo";
String literalString2 = "foo";
literalString1 == literalString2 // true

Поскольку это обе ссылки на пул строк.

Но как только вы начнете строить строки (используя +), будет создано new Строки в куче.Однако компилятор Java был умен и собрал два литерала String во время компиляции.

"wel"+"come" == "welcome"

Из-за того, что вы создаете их во время выполнения.Компилятор обнаружит "wel" + "come" строковый литерал и поместит его в пул строк.И "welcome" также является литералом, и будет искать пул строк, чтобы проверить, находится ли литерал в пуле строк.И, конечно, он найдет его и будет использовать ту же ссылку.

0 голосов
/ 11 июля 2011

Это потому, что компилятор разрешает "wel" + "come" как "welcome" перед компиляцией исходного кода ( оптимизировать это). Выражение может быть статически разрешено перед компиляцией, и компилятор делает это.

Затем оператор == возвращает true в первом случае, потому что оба являются одним и тем же объектом "welcome", хранящимся в пуле строк.

Это то же самое, что и вы:

0 голосов
/ 11 июля 2011

Для сравнения строк вы должны использовать метод String.equals.

0 голосов
/ 11 июля 2011

В java == сравнивает объекты по их ссылке, поэтому он вернет true, только если две переменные указывают на один и тот же объект.

В первом случае компилятор Java поймет, что "wel" +«come» является константой и использует один и тот же объект (указатель на пул констант) для s1 и для «wel» + «come».Во втором случае компилятор Java не будет знать, что это константа, и во время выполнения Java создаст новый объект при выполнении «wel» + s2, и сравнение не удастся.

В Java следует всегда и сбез исключения используйте метод .equals для сравнения двух строк.Ваша IDE также должна выдавать предупреждение, если записываете сравнение строк с ==.

0 голосов
/ 11 июля 2011

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

s1.equals("wel" + s2);

Ваш второй метод тестируется во время выполнения.Компилятор создает новый объект String и сравнивает ссылку на объект с новым объектом String.

0 голосов
/ 11 июля 2011

Попытка проверить строки на равенство путем сравнения их с оператором "==" - плохая вещь.Строки являются объектами, поэтому при использовании «==» вы сравниваете ссылки двух объектов, а не сами объекты.

Попробуйте вместо этого использовать метод equals ().

...