5 ответов:
ответ, как ни странно, равен нулю.
все
Integers от -128 до +127 предварительно вычисляются JVM.ваш код создает ссылки этим существующей объекты.
строго правильный ответ заключается в том, что количество объектов неопределено. Это может быть от 0 до 3, или 2561 или даже больше2 в зависимости от
- платформа Java3,
- будь это первый раз, когда этот код выполняется, и
- (потенциально) есть ли другой код, который полагается на бокс
intзначения выполняется перед это4.The
Integerзначения от -128 до 127 не обязательно должны быть предварительно. На самом деле,JLS 5.1.7 который указал преобразование бокса говорит следующее:если значение P в коробке является целочисленным литералом типа int между -128 и 127 включительно (§3.10.1) ... тогда пусть a и b-результаты любых двух боксерских преобразований p. всегда имеет место, что a == b.
две вещи, чтобы отметить:
- только JLS требует это >>литералы
- JLS не дает мандата готовностью кэширование значений. Ленивое кэширование также удовлетворяет поведенческим требованиям JLS.
даже javadoc для
Integer.valueof(int)не указать что результаты кэшируются с нетерпением.если мы рассмотрим исходный код Java SE для
java.lang.Integerиз Java 6 через 8 ясно, что текущая стратегия реализации Java SE заключается в предварительном вычислении значений. Однако по разным причинам (см. выше) этого все же недостаточно, чтобы дать однозначный ответ на вопрос "сколько объектов".
1-это может быть 256, если выполнение вышеуказанного кода инициализирует инициализацию класса для
Integerв версии Java, где кэш охотно инициализируется во время инициализации класса.2 - Это может быть даже больше, если кэш больше, чем требует спецификация JVM. Размер кэша может быть увеличен с помощью опции JVM в некоторых версиях Java.
3 - в дополнение к общему подходу платформы к реализации бокса компилятор может определить, что некоторые или все вычисления могут быть выполнены во время компиляции или полностью оптимизированы.
4-такой код может вызвать либо ленивую, либо нетерпеливую инициализацию целого числа кэш.
прежде всего: ответ, который вы ищете
0, Как уже упоминалось ранее.но давайте пойдем немного глубже. Как сказал Стивен ментион, это зависит от времени, когда вы его выполняете. Потому что кэш фактически лениво инициализирован.
если вы посмотрите на документацию java.ленг.Целое число.IntegerCache:
кэш инициализируется при первом использовании.
Это означает, что, если это первый раз, когда вы звоните любое целое число, вы на самом деле создать:
- 256 целочисленных объектов (или более: см. ниже)
- 1 объект для массива для хранения целых чисел
- давайте проигнорируем объекты, необходимые для хранения класса (и методов / полей). Они в любом случае хранятся в метапространстве.
со второго раза вы вызываете их, вы создаете 0 объектов.
вещи становятся более забавными, как только вы делаете цифры немного выше. Например, следующим образом: пример:
Integer i = 1500;допустимые параметры здесь: 0, 1 или любое число от 1629 до 2147483776 (на этот раз только подсчет созданных целочисленных значений. Зачем? Ответ дается в следующем предложении определения целочисленного кэша:
размер кэша может управляться параметром-XX:AutoBoxCacheMax=.
Так вы на самом деле можете изменить размер кэша, который реализуется.
что означает, что вы можете достичь выше линии:
- 1: новый объект, если ваш кэш меньше 1500
- 0: новые объекты, если ваш Кэш был инициализирован ранее и содержит 1500
- 1629: new (Integer) - объекты, если ваш кэш установлен точно в 1500 и еще не был инициализирован. Затем будут созданы целочисленные значения от -128 до 1500.
- как и в приведенном выше предложении, вы достигаете любого количества целочисленных объектов здесь до: Integer.MAX_VALUE + 129, который является упомянутым: 2147483776.
помните: это гарантируется только на Oracle / Open JDK (я проверил версии 7 и 8)
как вы можете видеть совершенно правильный ответ не так легко получить. Но просто говорю
0сделает людей счастливыми.
PS: с помощью параметра menthoned можно сделать следующее утверждение true:
Integer.valueOf(1500) == 1500
компилятор распаковывает
Integerобъектыints, чтобы сделать арифметику с ними, позвонивintValue()на них, и он называетInteger.valueOfв окнеintрезультаты, когда они назначаютсяIntegerпеременные, поэтому ваш пример эквивалентен:Integer i = Integer.valueOf(3); i = Integer.valueOf(i.intValue() + 1); Integer j = i; j = Integer.valueOf(i.intValue() + j.intValue());задание
j = i;- это совершенно нормальное назначение ссылки на объект, которое не создает новых объектов. Он не делает бокс или распаковку, и не нужно, какIntegerобъекты неизменный.The
valueOfметод позволяет кэшировать объекты и возвращать один и тот же экземпляр каждый раз для определенного числа. Это требуются в кэш целых чисел от -128 до +127. Для вашего стартового номераi = 3, все числа малы и гарантированно кэшируются, поэтому количество объектов, которые необходимо создать,0. Строго говоря,valueOfразрешено кэшировать экземпляры лениво, а не иметь их все заранее, так что пример может по-прежнему создавать объекты в первый раз, но если код выполняется повторно во время программы количество объектов, созданных каждый раз в среднем к 0.что делать, если вы начинаете с большим количеством экземпляров, которые не будут кэшироваться (например,
i = 300)? Тогда каждыйvalueOfвызов должен создать новыйIntegerобъект, и общее количество объектов, созданных каждый раз 3.(или, может быть, это все еще ноль, или, может быть это миллионы. Помните, что компиляторы и виртуальные машины могут переписывать код по причинам производительности или реализации, если его поведение не изменяется иным образом. Поэтому он может полностью удалить приведенный выше код, если вы этого не сделаете использовать результат. Или если вы попытаетесь напечатать
j, он мог бы понять, чтоjвсегда будет иметь одно и то же постоянное значение после приведенного выше фрагмента и, таким образом, выполнять всю арифметику во время компиляции и печатать постоянное значение. Действительность объем работы, выполняемой за кулисами для запуска вашего кода, всегда является детализацией реализации.)
вы можете отлаживать целое.valueOf (int i) метод, чтобы узнать это самостоятельно. Этот метод вызывается процессом автобокса компилятором.
Comments