Начиная с Java 1.5, вы можете в значительной степени обмениваться Integer
с int
во многих ситуациях.
Тем не менее, я обнаружил потенциальный дефект в моем коде, который немного удивил меня.
Следующий код:
Integer cdiCt = ...;
Integer cdsCt = ...;
...
if (cdiCt != null && cdsCt != null && cdiCt != cdsCt)
mismatch = true;
оказалось, что неправильно установить несоответствие, когда значения были равны, хотя я не могу определить, при каких обстоятельствах. Я установил точку останова в Eclipse и увидел, чтоInteger
оба значения были равны 137, и я проверил логическое выражение, и оно сказало, что оно ложно, но когда я перешагнул через него, было установлено несоответствие равным true.
Изменение условного на:
if (cdiCt != null && cdsCt != null && !cdiCt.equals(cdsCt))
исправил проблему.
Может кто-нибудь пролить свет на то, почему это произошло? До сих пор я видел только поведение моего локального хоста на своем ПК. В этом конкретном случае код успешно прошел около 20 сравнений, но не удался на 2. Проблема была постоянно воспроизводимой.
Если это распространенная проблема, она должна вызывать ошибки в других наших средах (dev и test), но до сих пор никто не сообщал о проблеме после сотен тестов, выполняющих этот фрагмент кода.
Разве это не законно использовать ==
для сравнения двух Integer
значений?
В дополнение ко всем точным ответам, приведенным ниже, следующая ссылка на stackoverflow содержит довольно много дополнительной информации. На самом деле он ответил бы на мой первоначальный вопрос, но поскольку я не упомянул автобокс в своем вопросе, он не появился в выбранных предложениях:
Почему компилятор / JVM не могут просто заставить автобокс работать?
Вы не можете сравнить два
Integer
с простыми==
объектами, так что большинство ссылок времени не будут одинаковыми.Есть хитрость, в
Integer
диапазоне от -128 до 127, ссылки будут такими же, как в автобоксах,Integer.valueOf()
которые кэшируют маленькие целые числа.Ресурсы :
На ту же тему:
источник
new Integer(1) == new Integer(1)
все еще ложь.new ... == new ...
всегдаfalse
.equals()
при работе с объектами. Это должно быть одной из первых вещей, которые нужно знать при изучении Java. Кстати, я бы предположил, что конструкторInteger
был закрытым, то есть экземпляры всегда создавались с помощьюvalueOf()
метода. Но я вижу, что конструктор является публичным.Проблема в том, что ваши два объекта Integer - это просто объекты. Они не совпадают, потому что вы сравниваете две ссылки на объекты, а не значения внутри. Очевидно
.equals
, переопределяется для обеспечения сравнения значений, а не сравнения ссылок на объекты.источник
Integer
относится к ссылке, то есть при сравнении ссылок, которые вы сравниваете, если они указывают на один и тот же объект, а не на значение. Следовательно, проблема, которую вы видите. Причина, по которой он так хорошо работает с простымиint
типами, заключается в том, что он распаковывает значение, содержащееся вInteger
.Могу ли я добавить, что если вы делаете то, что делаете, зачем
if
начинать это утверждение?источник
«==» всегда сравнивает ячейку памяти или ссылки на объекты значений. Метод equals всегда сравнивает значения. Но метод equals также косвенно использует оператор "==" для сравнения значений.
Integer использует кэш Integer для хранения значений от -128 до +127. Если оператор == используется для проверки любых значений в диапазоне от -128 до 127, он возвращает true. для других, чем эти значения он возвращает ложь.
Направить ссылку на какую - то дополнительную информацию
источник
Также для правильности использования
==
вы можете просто распаковать одно из сравниваемыхInteger
значений перед выполнением==
сравнения, например:Второй будет автоматически распакован (конечно, вы должны
null
сначала проверить s).источник
Помимо этих великих ответов я узнал, что:
источник