2013-06-25 2 views
8

Это касается разности результатов, возвращаемых оператором «+». Результат варьируется для строкового литерала и объекта String.+ Оператор в классе строк

String str="ab"; 
String str1="c"; 
String str2 = "ab"+"c"; // Line 3 
String str3 = "abc"; 
String str4 = str+str1; // Line 5 

System.out.println(str2==str3); // True 
System.out.println(str2==str4); // False 

С результатом мы можем заключить, что с буквальным, уже имеющимся объектом из строки пула возвращаются, как и в случае строки 3 и шпагат объекта нового объекта возвращаются, как и в строке 5. Почему это так ?

+0

Я сравнивал ссылочное равенство в этом случае. – Prashant

+0

+1, я также хочу знать, почему, хотя я предполагаю, что это потому, что вы назначаете литералы строку 1-4 и выполняете конкатенацию в str4. Я не уверен, что theres'a еще одна причина. – Thihara

ответ

9

+ oprator for String s обрабатывается по-разному в зависимости от времени, когда выражение может быть оценено.

Когда выражение может быть оценено во время компиляции (как в строке 3), компилятор создаст String, содержащий только конкатенацию. Поэтому в строке 3 будет создан только «String« abc », и этот String будет помещен в файл .class. Поэтому str3 и str4 будут точно такими же и будут интернированы.

При использовании конкатенации, которую можно оценить только во время выполнения (например, в строке 5) в результате String является новым String, которые должны быть сопоставлены WTH equals() как это новый объект.

3

String str2 = "ab"+"c"; оценивается в компиляция время. Он переходит в постоянный пул, поскольку он уже известен компилятору.

Другое может быть оценено в времени выполнения, оно не будет частью постоянного пула.

Это хорошая возможность отметить отличие от случая, когда вы используете String#concat, если вы

String str2 = "ab".concat("c");

Поскольку строка неизменен, новая строка возвращается из concat вызывая str не интернировали. Таким образом, в этом случае str2 == str3 будет false.

0

Я поставил вопрос как дубликат, но обнаружил, что аналогичный ответ не размещен, поэтому он думал о том, чтобы дать ему уйти. Другие ответы уже указывали, почему ответ неверен. Но вот что-то, что показывает вам, когда это будет правдой.

Если вы вызываете intern() на вторую строку, тогда результат будет true.

Почему это работает?

Чтобы сохранить память (и ускорить тестирование для равенства), Java поддерживает «интернирование» строк. Когда метод intern() вызывается в String, поиск выполняется в таблице интернированных строк. Если объект String с тем же содержимым уже находится в таблице, возвращается ссылка на String в таблице. В противном случае строка добавляется в таблицу и возвращается ссылка на нее.

String str4 = (str+str1).intern(); 

Явный вызов intern() возвращает ссылка на интернированы String.

0

Когда вы создадите str, str1, str2 и str3, он будет указывать на тот же пул строк. Если он не будет создавать строковый объект. Но когда вы создадите String str4 = str + str1.So str4 оценивается во время выполнения. Так что не будет частью того же пула строк, где все остальные строки указаны. Так что str4 возвращает false.

+0

Это неправда. Например, 'str == str1' является' false'. Они будут интернированы, если они будут вычислены во время компиляции и будут иметь одинаковое значение String. – Maroun