- это не точно. Строковые литералы всегда интернированы.

равнении двух строк меня учили, что мы не должны использовать логический оператор (==). Мы должны использовать String.equals (String) для сравнения. Тем не менее, я вижу, что следующий код соответствует и печатает "Hello Friend"с последней версией JDK (1.6_23). Я пытался искать и не мог найти никакой ссылки. С какого времени это происходит?

public class StringComp{
public static void main(String args[]){
        String s = "hello";
        if(s=="hello"){
                System.out.println("Hello Friend");
        }else{
                System.out.println("No Hello");
        }
    }
}
 Peter Lawrey20 янв. 2011 г., 11:52
Это должен быть самый распространенный вопрос в Java. Я предлагаю вам поработать над поисковыми навыками. ;)google.co.uk/search?q=java+string+comparison 17 миллионов просмотров
 finnw20 янв. 2011 г., 09:56
Я не думаю, что это дурак. Этот вопрос задает вопрос «почему это иногда работает», а не «почему это обычно не работает»
 user6982020 янв. 2011 г., 09:43
 finnw20 янв. 2011 г., 09:53
Смотрите такжеstackoverflow.com/questions/513832/... (принятый ответ относится к стажировке)
 Sundeep20 янв. 2011 г., 12:56
Я искал то же самое и несколько других. Ни в одной статье не упоминалось о «String Interning». Я знал, что это не способ сравнить две строки. Я был только удивлен, что это работает. Я потратил много времени, прежде чем осмелился спросить об этом. Благодарю вас.

Ответы на вопрос(7)

== сравнивает ссылки на объекты

Вы можете понять это, наблюдая вывод в следующем коде:

public class StringComp{
    public static void main(String args[]){
        String s = new String("hello");
        if(s=="hello"){
                System.out.println("Hello Friend");
        }else{
                System.out.println("No Hello");
        }
    }
}

Эта программа будет печататьNo hello

Потому что в этом коде переменнаяs ссылается на новый объект String, который в свою очередь ссылается на строковый литерал "hello" из пула String.

Решение Вопроса

== потому что это делает что-то еще, то вы думаете.

В этом случае «привет» сохраняется (Читать об интернировании строк), так что это «совпадение», что это то же самое, что и ваше движение.

== проверяет, являются ли две вещи ТОЧНО одинаковыми, а не имеют ли они одинаковое содержание. Это действительно большая разница, и некоторые случайные (хотя и объяснимые) «ложные возможности» не являются основанием для использования этого метода.

Просто используйте равно для сравнения строк.

С этого сайта пример:http://blog.enrii.com/2006/03/15/java-string-equality-common-mistake/

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

Он возвращает false, а следующий код возвращает true.

String a = new String ("a");
String b = new String ("a");
System.out.println (a.equals(b));
 Nanne20 янв. 2011 г., 09:49
Если добавить «интернирование», это слово я забыл;)

«Виртуальная машина Java поддерживает внутренний список ссылок для интернированных строк (пул уникальных строк), чтобы избежать дублирования объектов String в динамической памяти. когда JVM загружает литерал String из файла класса и выполняет, он проверяет, существует ли эта строка во внутреннем списке или нет. Если он уже существует в списке, он не создает новую String и использует ссылку на существующий объект String. JVM выполняет этот тип внутренней проверки для литерала String, но не для объекта String, который он создает с помощью 'new 'ключевое слово. Вы можете явно заставить JVM выполнять этот тип проверки для объектов String, которые создаются с помощью ключевого слова' new 'с использованием метода String.intern (). Это заставляет JVM проверять внутренний список и использовать существующий объект String, если он уже присутствует.

Таким образом, вывод заключается в том, что JVM поддерживает уникальные объекты String для строковых литералов внутри. Программистам не нужно беспокоиться о строковых литералах, но они должны беспокоиться об объектах String, которые создаются с помощью ключевого слова «new», и они должны использовать метод intern (), чтобы избежать дублирования объектов String в динамической памяти, что, в свою очередь, повышает производительность Java. см. следующий раздел для получения дополнительной информации. "

Ссылка:PreciseJava.com - Методы оптимизации в Strings и StringBuffer (как JVM работает со строками)

 Sundeep20 янв. 2011 г., 10:08
Спасибо за подробное объяснение.

х JVM), потому чтоs относится к строковому литералу"hello", Строковые ссылки, инициализированные литералами, относятся к литералу (который является глобальным объектом на заднем плане), а не к созданному отдельно новому объекту. Термин для этого, как и другие тоже упоминали,интернирование, таким образомs а также"hello" в вашем примере ссылаются на один и тот же физический объект. Рассмотреть возможность

String s1 = "hello";
String s2 = "hello";
String s3 = "hello";

Все эти строки ссылаются на один и тот же физический объект, таким образом, сравнение «==» между любой их парой или между любой из них и"hello" возвращаетсяtrue.

тем не мение

String s4 = new String ("hello");

создает новый объект, таким образомs4 == "hello" доходностьfalse.

 Sundeep20 янв. 2011 г., 10:02
Спасибо за подробный ответ. s2 == "привет" возвращает истину. s4 == "привет" возвращает false, верно ??
 Péter Török20 янв. 2011 г., 12:33
@ Sundeep, да, это была опечатка, теперь исправлена ​​:-)

В вашем случае вы выделяете два объекта String, оба из которых имеют значение "hello", а затем сравниваете их с ==. Компилятор может решить оптимизировать и использовать ту же ссылку на объект, давая реальный результат, подобный тому, который вы получили. Однако это не гарантированное поведение - гораздо безопаснее использовать equals () для сравнения значений.

 finnw20 янв. 2011 г., 09:59
«Компилятор может решить оптимизировать» - это не точно. Строковые литералы всегда интернированы.

== оператор используется, чтобы проверить, являются ли оба ссылки на один и тот же объект String, в то время как.equals сравнивает значения.

интернирование.

Яваинтерны Строковые литералы, и поэтому существует высокая вероятность того, что он оценивается как true:

String a = "hello";       // "hello" is assigned *and* interned
String b = "hello";       // b gets a reference to the interned literal
if (a == b)
   System.out.println("internd.");

String c = "hello" + Math.abs(1.0);   // result String is not interned
String d = "hello" + Math.abs(1.0);   // result String is not interned
System.out.println(c==d);             // prints "false"

c = c.intern();
System.out.println(c==d);             // prints "false"

d = d.intern();
System.out.println(c==d);             // prints "true"

Ваш ответ на вопрос