Как == сравнить местоположение в памяти?

Мне сказали никогда не использовать == для строк, но для всего остального, потому что .equals будет сравнивать значения, а не экземпляры объекта. (В чем я понимаю разницу).

Согласно некоторым сайтам, == сравнивает места памяти?

Чего я не понимаю, так это если вы сравниваете целое число с другим, зачем сравнивать места в памяти или это только для строк?

Если вы сравниваете int 3 с int 4, очевидно, что он не будет находиться в той же области памяти, но тогда, если вы сравниваете int 4 с int 4, означает ли это, что все целые числа со значением 4 хранятся в одном и том же месте? место в памяти?

9 ответов

Решение

== сравнивает значения операндов, будь то примитив или ссылочный тип.

  1. Если операнды являются примитивными, значения операндов будут сравниваться.

  2. Операнды, которые являются ссылками, содержат значения, т.е. адреса для доступа к объекту, на который они ссылаются. String не является примитивным типом данных, они рассматриваются как объекты в java. Когда вы сравниваете две ссылки типа string, результат будет истинным только тогда, когда значения операндов, т. Е. Адреса объектов String, равны (что означает, что они ссылаются на к тому же объекту String).

Согласно некоторым сайтам, == сравнивает места памяти?

Выражение a == b сравнивает содержание a а также b независимо от их типа.

Чего я не понимаю, так это если вы сравниваете целое число с другим, зачем сравнивать места в памяти или это только для строк?

В случае a а также b ссылки, == Оператор будет сравнивать "области памяти", так как это то, что содержат переменные.

В случае a а также b имеют примитивные типы, такие как int или же double переменные будут содержать фактические значения, следовательно, эти значения (а не их местоположение) будут сравниваться.

(Обратите внимание, что переменная никогда не может содержать такой объект, как String, это может самое большее указать на объект.)

Означает ли это, что все целые числа со значением 4 хранятся в одной и той же ячейке памяти?

Нет. Как объяснено выше, int Сравниваются "напрямую". Когда дело доходит до Integer история немного другая. Прежде всего new гарантирует, что вы получите новую ссылку, то есть

Object i = new Integer(5);
Object j = new Integer(5);

... i == j ...

всегда будет давать ложь.

Если вы пройдете через автобокс, однако:

Object i = (Integer) 5;
Object j = (Integer) 5;

... i == j ...

Вы получите истину из-за того, что автобокс проходит через кеш для значений в диапазоне -128-127. (См., Например, этот вопрос: Сравните два целых числа: почему == true?)

Проще говоря: дело в том, что int это примитивный тип, тогда как String это объект. Значения примитивных типов можно сравнить с == поскольку переменная указывает на само значение, а не на ссылку на значение.

Оператор == сравнивает ссылки на объекты в памяти, а строки являются объектами - примитивы не являются объектами, если они одного типа, тогда == будет работать. Как вы говорите, если они являются объектными вариантами примитивов (например, Integer для int), тогда java (>5) autoboxes для того, чтобы сделать сравнение.

== сравнивает ссылочные типы. int является примитивным типом.

так:

int x = 3;
int y = 3;

x==y is true

но с использованием ссылочного типа Integer

Integer x = new Integer(3);
Integer y = new Integer(3);

x == y is false

Из спецификации Java 15.21 Операторы равенства:

15.21. Операторы равенства

Операторы равенства синтаксически левоассоциативны (они группируются слева направо), но этот факт по сути никогда не полезен; например, a==b==c анализируется как (a==b)==c. Тип результата a == b всегда логический, поэтому c должен иметь тип логический, иначе произойдет ошибка времени компиляции. Таким образом, a==b==c не проверяет, равны ли все a, b и c.

EqualityExpression: RelationalExpression EqualityExpression == RelationalExpression EqualityExpression!= RelationalExpression Операторы == (равно) и!= (Не равно) аналогичны операторам отношения, за исключением их более низкого приоритета. Таким образом,

Во всех случаях a!= B дает тот же результат, что и!(A ==b). Операторы равенства являются коммутативными, если выражения операндов не имеют побочных эффектов.

15.21.1 Операторы числового равенства == и!=

Если оба операнда оператора равенства имеют числовой тип или один имеет числовой тип, а другой преобразуется (§5.1.8) в числовой тип, двоичные числовые преобразования выполняются над операндами (§5.6.2). Если повышенный тип операндов - int или long, то выполняется тест на целочисленное равенство; если повышенный тип является float или double, то выполняется тест на равенство с плавающей точкой. Обратите внимание, что двоичное числовое продвижение выполняет преобразование набора значений (§5.1.13) и преобразование распаковки (§5.1.8). Сравнение выполняется точно по значениям с плавающей точкой, независимо от того, из каких наборов значений были получены их представляющие значения.

Тестирование на равенство с плавающей точкой выполняется в соответствии с правилами стандарта IEEE 754:

Если любой из операндов равен NaN, то результат == равен false, а результат!= Равен true. Действительно, тест x!= X верен тогда и только тогда, когда значение x равно NaN. (Методы Float.isNaN и Double.isNaN также могут использоваться для проверки, является ли значение NaN.) Положительный ноль и отрицательный ноль считаются равными. Поэтому, -0.0==0.0 верно, например. В противном случае два различных значения с плавающей точкой считаются неравными операторами равенства. В частности, есть одно значение, представляющее положительную бесконечность, и одно значение, представляющее отрицательную бесконечность; каждый сравнивает равный только сам по себе, и каждый сравнивает неравный со всеми другими значениями. С учетом этих соображений для чисел с плавающей запятой следующие правила сохраняются для целочисленных операндов или для операндов с плавающей запятой, отличных от NaN: значение, создаваемое оператором ==, равно true, если значение левого операнда равно значение правого операнда; в противном случае результат ложен. Значение, созданное оператором!=, Имеет значение true, если значение левого операнда не равно значению правого операнда; в противном случае результат ложен. 15.21.2 Операторы булевого равенства == и!=

Если оба операнда оператора равенства имеют тип boolean, или если один операнд имеет тип boolean, а другой - тип Boolean, то операция имеет логическое равенство. Операторы булевого равенства ассоциативны. Если один из операндов имеет тип Boolean, он подвергается распаковке преобразования (§5.1.8).

Результат == равен true, если операнды (после любого необходимого преобразования без распаковки) оба имеют значение true или оба имеют значение false; в противном случае результат ложен.

Результат!= False, если оба операнда имеют значение true или оба имеют значение false; в противном случае результат верен. Таким образом!= Ведет себя так же, как ^ (§15.22.2), когда применяется к булевым операндам.

15.21.3 Операторы ссылочного равенства == и!=

Если операнды оператора равенства имеют либо ссылочный тип, либо нулевой тип, то операция является объектным равенством. Ошибка времени компиляции происходит, если невозможно преобразовать тип одного операнда в тип другого путем преобразования преобразования (§5.5). Значения времени выполнения двух операндов обязательно будут неравными.

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

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

Хотя == может использоваться для сравнения ссылок типа String, такой тест на равенство определяет, ссылаются ли два операнда на один и тот же объект String. Результат равен false, если операнды - это разные объекты String, даже если они содержат одинаковую последовательность символов. Содержимое двух строк s и t можно проверить на равенство с помощью вызова метода s.equals (t). Смотрите также §3.10.5.

intЭто примитивные типы в java, и как таковые они не представляют объектную "ссылку", а непосредственно значение.

Объекты равны по значению, но значение, которое имеют объекты, является ссылкой на область памяти. Примитивы (т. Е. Int, boolean, char, double) не используют ссылки, но хранят их значение. Поэтому, когда используется ==, он сравнивает значение двух. В случае объектов это ссылка; однако в случае примитивов это значение, которое он хранит.

== оператор сравнивает ints по значению и объекты по адресу. Таким образом, == правильно для intс, но (обычно) не для Strings.

Обратите внимание, что если вы знаете, что оба Stringбыли возвращены String.intern метод, == работает правильно, как intern гарантированно вернуть тот же адрес для идентичных строк.

Другие вопросы по тегам