Загадочное поведение == после постинкрементации [дубликат]


На этот вопрос уже есть ответ здесь:

Кто-то постулировал в какой-то теме форума, что многие люди и даже опытные разработчики Java не поймут следующий мир кода Java.

Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1++ == i2++);
System.out.println(i1 == i2);

Как человек с определенным интересом на Яве я высказал ему свои мысли и пришел к следующему результату.

System.out.println(i1++ == i2++);
// True, since we first check for equality and increment both variables afterwards.

System.out.println(i1 == i2);
// True again, since both variables are already incremented and have the value 128
Затмение говорит мне обратное. Первая строка является истинной, а вторая-ложной.

Я действительно был бы признателен за разъяснение.

Второй вопрос. Является ли это специфичным для Java или этот пример также применим, например, к языкам на основе C?

2 9

2 ответа:

Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1++ == i2++); 
// here i1 and i2 are still 127 as you expected thus true
System.out.println(i1 == i2); 
// here i1 and i2 are 128 which are equal but not cached
    (caching range is -128 to 127), 

В случае 2, Если вы используете equals(), он вернет true, так как оператор == для целых чисел работает только для кэшированных значений. поскольку 128 находится вне диапазона кэша, значения выше 128 не будут кэшироваться, поэтому вы должны использовать метод equals(), чтобы проверить, являются ли два целых экземпляра выше 127 истинными

Тест:

Integer i1 = 126;
    Integer i2 = 126;
    System.out.println(i1++ == i2++);// true
    System.out.println(i1 == i2); //true



 Integer i1 = 126;
        Integer i2 = 126;
        System.out.println(i1++ == i2++);// true
        System.out.println(i1.equals(i2)); //true

  Integer i1 = 128;
        Integer i2 = 128;
        System.out.println(i1++ == i2++);// false
        System.out.println(i1==i2); //false

  Integer i1 = 128;
        Integer i2 = 128;
        System.out.println(i1++.equals(i2++));// true
        System.out.println(i1.equals(i2)); //true

Как объяснено, это связано сцелочисленным кэшированием . Для развлечения вы можете запустить программу со следующей опцией JVM:

-XX:AutoBoxCacheMax=128

И он будет печатать true дважды (опция доступна на hostpot 7 - не обязательно на других JVMs).

Обратите внимание, что:

  • это специфический JVM
  • модифицированное поведение соответствует JLS, который говорит, что все значения между -128 и +127 должны быть кэшированы, но также говорит, что другие значениямогут быть кэшированный.

Итог: второй оператор print не определен в Java и может печатать true или false в зависимости от используемой реализации JVM и/или параметров JVM.