Как == сравнить местоположение в памяти? - PullRequest
4 голосов
/ 11 ноября 2011

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

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

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

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

Ответы [ 9 ]

12 голосов
/ 11 ноября 2011

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

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

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

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

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

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

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

Нет. Как объяснено выше, int s сравниваются "напрямую". Когда дело доходит до 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? )

4 голосов
/ 11 ноября 2011

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

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

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

2 голосов
/ 11 ноября 2011

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

1 голос
/ 11 ноября 2011

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

1 голос
/ 11 ноября 2011

== сравнивает ссылочные типы. 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
1 голос
/ 11 ноября 2011

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

0 голосов
/ 05 марта 2013

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

0 голосов
/ 11 ноября 2011

Из спецификации 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 The == (равно) иоператоры! = (не равные) аналогичны операторам отношений, за исключением их более низкого приоритета.Таким образом, a

Во всех случаях 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.

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

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

0 голосов
/ 11 ноября 2011

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

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

...