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

Сравнение значений Integer в Java, странное поведение

Прогулка со мной..

Integer x = 23;
Integer y = 23;

if (x == y)
    System.out.println("what else");      // All is well as expected
else
    System.out.println("...");

Пока

Integer x = someObject.getIndex();
Integer y = someOtherObject.getSomeOtherIndex();

if (x == y)
    System.out.println("what else");  
else
    System.out.println("...");        // Prints this 

Хмм... Я пробовал лить в int

int x = someObject.getIndex();
int y = someOtherObject.getSomeOtherIndex()

if (x == y)       
    System.out.println("what else");   // works fine
else
    System.out.println("...");  

Являются ли они оба целыми?

System.out.println(x.getClass().getName());              // java.lang.Integer
System.out.println(y.getClass().getName());              // java.lang.Integer
System.out.println(someObject.getIndex());               // java.lang.Integer
System.out.println(someOtherObject.getSomeOtherIndex()); // java.lang.Integer

Что вы, ребята, думаете? Что бы это объясняло?

4b9b3361

Ответ 1

Вы сравниваете значения Integer, которые являются ссылками. Вы придумываете эти ссылки через autoboxing. Для некоторых значений (гарантируется от -128 до 127) JRE поддерживает кеш объектов Integer. Для более высоких значений это не так. Из раздел 5.1.7 JLS:

Если значение p в боксе равно true, false, байту или char в диапазоне от \u0000 до\u007f или int или коротком числе между -128 и 127 (включительно), тогда пусть r1 и r2 - результаты любых двух бокс-преобразований p. Всегда бывает, что r1 == r2.

В идеале, бокс данного примитивного значения p всегда будет давать идентичную ссылку. На практике это может оказаться невозможным с использованием существующих методов внедрения. Правила выше - прагматичный компромисс. Последнее заключительное предложение требует, чтобы определенные общие значения всегда помещались в неразличимые объекты. Реализация может кэшировать эти, лениво или нетерпеливо. Для других значений эта формулировка запрещает любые предположения о идентичности вложенных значений в части программиста. Это позволило бы (но не требовать) совместного использования некоторых или всех этих ссылок.

Это гарантирует, что в большинстве распространенных случаев поведение будет желательным, не налагая чрезмерного штрафа за производительность, особенно на небольшие устройства. Менее ограниченные памятью реализации могут, например, кэшировать все char и короткие значения, а также значения int и long в диапазоне от -32K до + 32K.

Мораль: не сравнивайте ссылки Integer, когда вас интересуют базовые значения int. Используйте .equals() или сначала получите значения int.

Ответ 2

Чтобы правильно сравнить целые числа, вам нужно использовать .equals() или сравнить их примитивные значения, нажав на int или называя intValue() на них.

Использование == проверяет, являются ли два целых объекта одним и тем же объектом, но не содержат ли они одинаковое числовое значение.

    Integer a = new Integer(1);
    Integer b = new Integer(1);

    System.out.println(a.equals(b));                  //true
    System.out.println((int)a == (int)b);             //true
    System.out.println(a.intValue() == b.intValue()); //true
    System.out.println(a == b);                       //false

Отредактировано, чтобы проиллюстрировать точку Джона из JLS об автобоксинге:

    Integer a = 1;
    Integer b = 1;
    System.out.println(a.equals(b));                  //true
    System.out.println((int)a == (int)b);             //true
    System.out.println(a.intValue() == b.intValue()); //true
    System.out.println(a == b);                       //true

против

    Integer a = 128;
    Integer b = 128;
    System.out.println(a.equals(b));                  //true
    System.out.println((int)a == (int)b);             //true
    System.out.println(a.intValue() == b.intValue()); //true
    System.out.println(a == b);                       //false

Ответ 3

Похоже, что что-то напугано с автоматическим боксом, когда вы используете == для двух целых чисел.

Я бы предположил, что он отлично работает при использовании Integer, если вы используете метод equals()? Это, по моему мнению, все равно.

Вы не используете java 1.4 или что-то не так ли?