Java: Почему доказательство равенства строк можно проверить с помощью ==?
Я узнал, что от дьявола проверять равенство строк с ==
вместо String.equals()
, потому что каждая строка была ссылкой на свой собственный объект.
Но если я использую что-то вроде
System.out.println("Hello" == "Hello");
он выводит true.
Почему?
Ответы
Ответ 1
Это не так. Это все еще плохо, но вы все равно будете тестировать ссылочное равенство вместо равенства ценности.
public class Test
{
public static void main(String[] args)
{
String x = "hello";
String y = new String(x);
System.out.println(x == y); // Prints false
}
}
Если вы видите == тестирование "работа" сейчас, то это потому, что вы действительно имеете равные ссылки. Наиболее распространенной причиной для этого было бы, вероятно, из-за интернирования литералов String, но это было в Java навсегда:
public class Test
{
public static void main(String[] args)
{
String x = "hello";
String y = "hel" + "lo"; // Concatenated at compile-time
System.out.println(x == y); // Prints true
}
}
Это гарантируется в разделе 3.10.5 спецификации языка Java:
Каждый строковый литерал является ссылкой (П. 4.3) к инстанции (п. 4.3.1, п. 12.5) класса String (п. 4.3.3). строка объекты имеют постоянное значение. строка литералы - или, в более общем смысле, строки которые являются значениями постоянной выражения (§15.28) - "интернированы", поэтому как обмениваться уникальными экземплярами, используя метод String.intern.
Ответ 2
Он не изменился. Однако Java Compiler использует string.intern(), чтобы убедиться, что идентичные строки в исходном коде компилируются для одного объекта String. Если, однако, вы загружаете String из файла или базы данных, это не будет тот же объект, если вы не принудительно это используете с помощью String.intern() или какого-либо другого метода.
Это плохая идея, и вы все равно должны использовать .equals()
Ответ 3
Посмотрите, это сложная концепция.
Существует различие между:
// These are String literals
String a = "Hiabc";
String b = "abc";
String c = "abc";
и
// These are String objects.
String a = new String("Hiabc");
String b = new String("abc");
String c = new String("abc");
Если ваши строки были объектами, т.е.
String b = new String("abc");
String c = new String("abc");
Затем два разных объекта были бы созданы в пуле String в двух разных ячейках памяти и выполняли
b == c
привел бы false
.
Но так как ваши String b
и String c
являются литералами,
b == c
Результаты true
. Это связано с тем, что не созданы два разных объекта. И оба a
и b
указывают на ту же строку в памяти стека.
В этом разница. Вы правы, ==
сравнивает место памяти. И в этом причина,
a.substring(2, 5) == b; // a,substring(2, 5) = "abc" which is at the location of b, and
b == c // will be true, coz both b and c are literals. And their values are compared and not memory locations.
Чтобы иметь две отдельные строки с одинаковыми значениями, но в разных местах в String pool
и NOT stack memory
, вам необходимо создать объекты String, как показано выше.
Итак,
a.substring(2, 5) == b; // and
b == c; // will be false. as not both are objects. Hence are stored on separate memory locations on the String pool.
вы должны использовать
a.substring(2, 5).equals(b);
b.equals(c);
в случае объектов.