Сравнение объектов оператором == в Java. Integer vs int

212
20 февраля 2019, 23:10

Для сравнения объектов в Java используется метод equals(), но что если сравниваются между собой два объекта-обертки для примитивных типов:

Integer a = 120;
Integer b = 120;
Integer c = 130;
Integer d = 130;
System.out.println(a==b); // true
System.out.println(c==d); // false

Почему в первом случае возвращается true, а во втором false?

Answer 1

Класс Integer содержит кэш обёрток для значений от -128 до 127.

Если число лежит в этом диапазоне и обёртки нет в кэше, то создаётся новая обёртка и помещается в кэш для последущего использования.

Если не в диапазоне, то каждый раз создаётся новая обёртка и при сравнении вы получите false, так как объекты разные

Подробнее в исходниках метода valueOf

public static Integer valueOf(int val)
{
  if (val < MIN_CACHE || val > MAX_CACHE)
    return new Integer(val);
    synchronized (intCache)
    {
        if (intCache[val - MIN_CACHE] == null)
            intCache[val - MIN_CACHE] = new Integer(val);
        return intCache[val - MIN_CACHE];
    }
}

Для сравнения по значению можно привести один из объктов к примитивному типу:

System.out.println((int)a == b)
Answer 2

В Java доках в классе Integer сказано:

/**
 * Cache to support the object identity semantics of autoboxing for values between
 * -128 and 127 (inclusive) as required by JLS.
 *
 * The cache is initialized on first usage.  The size of the cache
 * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
 * During VM initialization, java.lang.Integer.IntegerCache.high property
 * may be set and saved in the private system properties in the
 * sun.misc.VM class.
 */

То есть по умолчанию кешируются значения между -128 и 127, как указано в JLS. Если значение попадает в этот диапазон, то оно берется из кеша, если нет, то сравниваться будут объекты.

Размером кеша можно управлять, изменяя параметры JVM:

-XX:AutoBoxCacheMax=<cache_max_value>

либо

-Djava.lang.Integer.IntegerCache.high=<cache_max_value>
READ ALSO
Повторить одну строку в столбик, через итератор и цикл (при условии)

Повторить одну строку в столбик, через итератор и цикл (при условии)

Нужно реализовать повтор строки в столбик 1 раз (если то условие выполняется)Ниже выделил где именно это происходит

182
Как использовать logger.info(из log4j) в консоли вместо print?

Как использовать logger.info(из log4j) в консоли вместо print?

Надо выводить какие-то действия в консоль + логировать их в файлЯ сделал это с помощью log4j

177
java CsvToBeanBuilder

java CsvToBeanBuilder

Пытаюсь считать csv файл

222
JNI 64 бит x64 на FASM или ASM

JNI 64 бит x64 на FASM или ASM

Хочу написать взаимодействие jni и fasm на x64 битной архитектуре и возникла небольшая проблема

244