Когда я изучаю исходный код некоторых продуктов с открытым исходным кодом, я нахожу такой код:
if (a=="cluser")
a
— это строковая переменная. Можно ли заменить операцию String equals
на ==
?
Когда я изучаю исходный код некоторых продуктов с открытым исходным кодом, я нахожу такой код:
if (a=="cluser")
a
— это строковая переменная. Можно ли заменить операцию String equals
на ==
?
Вы должны почти никогда использовать ==
и почти всегда использовать equals()
. Он будет работать только с ==
, если обе строки ссылаются на один и тот же объект. В String
есть метод intern()
для возврата той же ссылки для заданного строкового значения. Строковые литералы неявно интернированы. Только если у вас есть очень веская причина, вы должны использовать ==
для сравнения строк, и даже в этом случае вам нужно быть очень осторожным.
Единственной хорошей причиной является производительность, и очень редко это будет иметь значение. Оптимизируйте только тогда, когда вы точно знаете, что вам это нужно. В противном случае обычно не стоит хлопот. Если вы просматриваете некоторый открытый исходный код, у них может быть случай, когда сравнение находится в очень узком цикле или вызывается очень часто, и оптимизация может помочь. Или он был просто преждевременно оптимизирован и, возможно, казался безопасным.
Вы можете использовать ==, если две строки интернированы. Строковые литералы определены как интернированные, поэтому, если я, скажем, назначу литерал «fred» переменной String и передам его в качестве параметра методу в другом классе, где он сравнивается с «fred», тест == будет истинный.
Так что образец кода не то чтобы дефектный, скорее всего так.
только если строки были «интернированы». Обычно нет.
Из Спецификации языка Java, раздел 3.10.5 Строковые литералы.
Каждый строковый литерал является ссылкой на экземпляр класса String. Строковые объекты имеют постоянное значение. Строковые литералы или, в более общем случае, строки, являющиеся значениями константных выражений, "интернированы" для совместного использования уникальных экземпляров с помощью метода String.intern.
Итак, тестовая программа, состоящая из блока компиляции:
package testPackage;
class Test {
public static void main(String[] args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((other.Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }
и модуль компиляции:
package other;
public class Other { static String hello = "Hello"; }
производит вывод:
true true true true false true
Этот пример иллюстрирует шесть моментов:
Оператор == проверяет, являются ли два объекта одним и тем же объектом. Он не сравнивает то, что находится в строках.
==
по-прежнему означает равенство ссылок на объекты. Код, который вы читаете, неверен, если он пытается выполнить сравнение строк. - person wkl   schedule 30.04.2011