Подтвердить что ты не робот

Что делает сравнение ссылок (==) для некоторых строк в Java?

У меня есть следующие строки кодов для сравнения String. str1 не равно str2, что понятно, поскольку сравнивает ссылку на объект. Но тогда почему s1 равно s2?

String s1 = "abc";
String s2 = "abc";

String str1 = new String("abc");
String str2 = new String("abc");

if (s1==s2)
    System.out.println("s1==s2");           
else
    System.out.println("s1!=s2");

if (str1==str2)
    System.out.println("str1==str2");           
else
    System.out.println("str1!=str2");

if (s1==str1)
    System.out.println("str1==s1");         
else
    System.out.println("str1!=s1");

Вывод:

  s1==s2
  str1!=str2
  str1!=s1 
4b9b3361

Ответ 1

Строковый пул констант по существу кэширует все строковые литералы, поэтому они являются одним и тем же объектом, поэтому вы видите вывод, который вы делаете для s1==s2. Это, по сути, оптимизация в виртуальной машине, чтобы избежать создания нового строкового объекта каждый раз, когда объявляется литерал, который может очень быстро стать очень дорогостоящим! С вашим примером str1==str2 вы явно говорите виртуальной машине о создании новых строковых объектов, поэтому почему она неверна.

Как в стороне, вызов метода intern() в любой строке добавит его в пул констант (и вернет String, который он добавил в пул). Это не обязательно хорошая идея для этого, однако, если вы не убедитесь, что вы имеете дело со строками, которые определенно будут использоваться в качестве констант, иначе вы можете создать сложную задачу для отслеживания утечек памяти.

Ответ 2

s1 и s2 - строковые литералы. Когда вы создаете новый строковый литерал, компилятор сначала проверяет, присутствует ли какой-либо литерал, представляющий его, в пуле строк или нет. Если есть один экземпляр, компилятор возвращает этот литерал, иначе компилятор создает новый.

Когда вы создали String s2, компилятор возвращает String s1 из пула, как он уже был создан ранее. Вот почему s1 и s2 одинаковы. Это поведение называется интернированием.

Ответ 3

Это явление связано с Интерпретация строк.

В принципе, все строковые литералы "кэшируются" и повторно используются.

Ответ 4

Это происходит из-за интернирования строк. В этом вопросе документация Java говорит:

Все литералы и строковые константные выражения интернировано

И это объясняет, почему s1 и s2 одинаковы (эти две переменные указывают на одну и ту же интернированную строку)

Ответ 5

В Java одни и те же константные строки будут повторно использоваться. Чтобы s1 и s2 указывали на один и тот же объект "abc" и s1==s2. Но когда вы используете new String("abc"), будет создан другой объект. Так что s1 != str1.

Ответ 6

Поскольку string является неизменным в java, все string literals кэшируются для повторного использования.

При создании объекта String с помощью new() оператор всегда создает новый объект в кучевой памяти. С другой стороны, если вы создаете объект, используя синтаксис строкового литерала, например. "Java", он может вернуть существующий объект из пула String (кеш объекта String в пространстве Perm gen, который теперь перемещается в кучу пространства в последнем выпуске Java), если он уже существует. В противном случае он создаст новый строковый объект и добавит пул строк для последующего повторного использования.

String s1 = new String("java");
String s2 = new String("java");
String s3 = "java";
String s4 = "java";

введите описание изображения здесь

Обратитесь к этой ссылке