Почему равный оператор работает для значения Integer до 128 числа?
Почему Integer «=» оператор не работает для 128 и после значений Integer? Может ли кто-нибудь объяснить эту ситуацию?
Это моя среда Java: версия java «1.6.0_37»
Java (TM) SE Runtime Environment (assembly 1.6.0_37-b06)
- В Java существует ли способ написать строковый литерал без необходимости скрывать кавычки?
- Что означает «public static void» в Java?
- Создание базы данных MySQL с Java
- JPA (Hibernate) и пользовательские префиксы таблиц
- Самый быстрый способ найти недостающее число в массиве чисел
Java HotSpot (TM) 64-разрядная серверная VM (assembly 20.12-b01, смешанный режим)
Образец кода:
Integer a; Integer b; a = 129; b = 129; for (int i = 0; i < 200; i++) { a = i; b = i; if (a != b) { System.out.println("Value:"+ i + " - Different values"); } else { System.out.println("Value"+ i + " Same values"); } }
Некоторая часть консольного вывода:
Value:124 - Same values Value:125 - Same values Value:126 - Same values Value:127 - Same values Value:128 - Different values Value:129 - Different values Value:130 - Different values Value:131 - Different values Value:132 - Different values
Благодаря!
- Группировать по нескольким именам полей в java 8
- Regex найти целые слова
- существует ли эквивалент Java, эквивалентный нулевому коалесцирующему оператору (??) в C #?
- Java-массивы печатают странные цифры и текст
- Почему заголовок JTable не отображается на изображении?
- Как выполнить строку Diffs в Java?
- Java - порядок операций - использование двух операторов присваивания в одной строке
- Какой смысл разрешать свидетелям типов во всех вызовах методов?
Проверьте исходный код Integer . Вы можете увидеть кеширование значений там.
Кэширование происходит, только если вы используете Integer.valueOf(int)
, а не если используете new Integer(int)
. Используемый вами Integer.valueOf
использует Integer.valueOf
Согласно JLS , вы всегда можете рассчитывать на то, что для значений от -128 до 127 вы получаете идентичные объекты Integer после автобоксинга, а на некоторых реализациях вы можете получить одинаковые объекты даже для более высоких значений.
Фактически в Java 7 (и я думаю, что в новых версиях Java 6) реализация classа IntegerCache изменилась, а верхняя граница больше не жестко запрограммирована, но настраивается через свойство «java.lang.Integer.IntegerCache. high “, поэтому, если вы запустите свою программу с параметром VM -Djava.lang.Integer.IntegerCache.high=1000
, вы получите« одинаковые значения »для всех значений.
Но JLS все еще гарантирует это только до 127:
В идеале, бокс данного примитивного значения p всегда будет давать идентичную ссылку. На практике это может оказаться невозможным с использованием существующих методов внедрения. Правила выше – прагматичный компромисс. Последнее заключительное предложение требует, чтобы определенные общие значения всегда помещались в неразличимые объекты. Реализация может кэшировать эти, лениво или нетерпеливо.
Для других значений эта формулировка запрещает любые предположения о идентичности вложенных значений на части программиста. Это позволило бы (но не требовать) совместного использования некоторых или всех этих ссылок.
Это гарантирует, что в большинстве распространенных случаев поведение будет желательным, не налагая чрезмерного штрафа за производительность, особенно на небольшие устройства. Меньшие реализации, ограниченные памятью, могут, например, кэшировать все символы и шорты, а также целые и длинные строки в диапазоне от -32K до + 32K.
Integer
– это class оболочки для int
.
Integer != Integer
сравнивает фактическую ссылку на объект, где int != int
будет сравнивать значения.
Как уже указывалось, значения -128 – 127 кэшируются, поэтому для них возвращаются одни и те же объекты.
Если вне этого диапазона, будут созданы отдельные объекты, поэтому ссылка будет отличаться.
Исправить это:
- Сделайте типы
int
или - Передать типы в
int
или - Использовать
.equals()
Согласно спецификациям Java Language:
Если значение p, помещенное в поле, равно true, false, байт, символ в диапазоне от \ u0000 до \ u007f или int или short number между -128 и 127, то пусть r1 и r2 будут результатом любых двух преобразований в боксе из. Всегда бывает, что r1 == r2.
JLS Boxing Conversions
Обратитесь к этой статье за дополнительной информацией о кэшировании int
Объект Integer имеет внутренний механизм кэширования:
private static class IntegerCache { static final int high; static final Integer cache[]; static { final int low = -128; // high value may be configured by property int h = 127; if (integerCacheHighPropValue != null) { // Use Long.decode here to avoid invoking methods that // require Integer's autoboxing cache to be initialized int i = Long.decode(integerCacheHighPropValue).intValue(); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - -low); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {} }
Также см. Метод valueOf:
public static Integer valueOf(int i) { if(i >= -128 && i <= IntegerCache.high) return IntegerCache.cache[i + 128]; else return new Integer(i); }
Вот почему вы должны использовать valueOf
вместо new Integer
. Autoboxing использует этот кеш.
Также см. Это сообщение: https://effective-java.com/2010/01/java-performance-tuning-with-maximizing-integer-valueofint/
Использование ==
- это не очень хорошая идея, используйте equals для сравнения значений.
Используйте .equals()
вместо ==
.
Целочисленные значения кэшируются только для чисел от -127 до 128, потому что они используются чаще всего.
if (a.equals(b)) { ... }
В зависимости от того, как вы получаете экземпляры Integer
, он может не работать для какого-либо значения:
System.out.println(new Integer(1) == new Integer(1));
печать
false
Это связано с тем, что оператор ==
применяемый к операндам с типизированным типом, не имеет ничего общего со значением, которое представляют эти операнды.
Это потому, что логика реализации classа Integer
. Он подготовил объекты для чисел до 128. Вы можете проверить http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Integer.java источник открытого -jdk, например (поиск кеша []).
В принципе, объекты не следует сравнивать с помощью ==
вообще, за одним исключением из Enums.