Тест равенства Java Wrapper

  public class WrapperTest {

    public static void main(String[] args) {

        Integer i = 100;
        Integer j = 100;

        if(i == j)
            System.out.println("same");
        else
            System.out.println("not same");
    }

   }

Вышеприведенный код выводит результат same при запуске, однако, если мы изменим значение i и j на 1000, выход изменится на not same. Поскольку я готовлюсь к SCJP, нужно понять эту концепцию. Может кто-то объяснить это поведение. Спасибо.

Ответ 1

В Java целые числа от -128 до 127 (включительно) обычно представлены одним и тем же экземпляром объекта Integer. Это связано с использованием внутреннего класса IntegerCache (содержащегося внутри класса Integer и используемого, например, при вызове Integer.valueOf() или во время автобоксинга):

private static class IntegerCache {
    private IntegerCache(){}

    static final Integer cache[] = new Integer[-(-128) + 127 + 1];

    static {
        for(int i = 0; i < cache.length; i++)
            cache[i] = new Integer(i - 128);
    }
}

Смотрите также: http://www.owasp.org/index.php/Java_gotchas

Ответ 2

В принципе, целые числа между -127 и 127 "кэшируются" таким образом, что при использовании этих чисел вы всегда ссылаетесь на один и тот же номер в памяти, поэтому ваш == работает.

Любое целое вне этого диапазона не кэшируется, поэтому ссылки не совпадают.

Ответ 3

@tunaranch - это правильно. Это также та же проблема, что и в этом Python вопросе. Суть в том, что Java хранит объект вокруг целых чисел от -128 до 127 (Python делает -5 до 256) и возвращает один и тот же объект каждый раз, когда вы его запрашиваете. Если вы запрашиваете Integer вне этого фиксированного диапазона, каждый раз он будет давать вам новый объект.

(Напомним, что == возвращает, являются ли два объекта фактически одинаковыми, а equals сравнивает их содержимое.)

Изменить: здесь соответствующий абзац из Раздел 5.1.7 Спецификация языка Java:

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

Обратите внимание, что это также описывает, что происходит с другими типами.

Ответ 5

Ваш код не компилируется. Это то, что я получаю:

Исключение в потоке "main" java.lang.Error: нерешенные проблемы компиляции:     Тип несоответствия: невозможно преобразовать из int в Integer     Тип несоответствия: невозможно преобразовать из int в Integer

at WrapperTest.main(WrapperTest.java:5)

Переменные я и j являются экземплярами объекта Integer. Не сравнивайте экземпляры объекта с помощью оператора "==", вместо этого используйте метод "equals".

Привет