Я понятия не имею, почему эти строки кода возвращают разные значения:
System.out.println(Integer.valueOf("127")==Integer.valueOf("127"));
System.out.println(Integer.valueOf("128")==Integer.valueOf("128"));
System.out.println(Integer.parseInt("128")==Integer.valueOf("128"));
Выход:
true
false
true
Почему первый возвращается, true
а второй возвращается false
? Есть ли что-то другое, что я не знаю между 127
и 128
? (Конечно, я знаю, что 127
< 128
.)
Кроме того, почему третий возвращается true
?
Я прочитал ответ на этот вопрос , но до сих пор не понял, как он может вернуться true
и почему возвращается код во второй строке false
.
.equals()
, иначе все ставки выключены.Ответы:
Здесь есть разительная разница.
valueOf
возвращаетInteger
объект, значения которого могут быть кэшированы в диапазоне от -128 до 127. Вот почему первое значение возвращаетсяtrue
- оно кэшируется, а второе возвращаетсяfalse
- 128 не является кэшированным значением, поэтому вы получаете два отдельныхInteger
экземпляра ,Важно отметить, что вы сравниваете ссылки
Integer#valueOf
, и если вы сравниваете значение, которое больше, чем поддерживает кэш, оно не будет оцениватьсяtrue
, даже если проанализированные значения эквивалентны (в данном случае:)Integer.valueOf(128) == Integer.valueOf(128)
. Вы должны использоватьequals()
вместо этого.parseInt
возвращается примитивint
. Поэтому возвращается третье значениеtrue
-128 == 128
оценивается, и, конечно же ,true
.Теперь случается так, что получается третий результат
true
:Преобразование распаковки происходит в отношении оператора эквивалентности, который вы используете, и ваших типов данных, а именно,
int
иInteger
. Вы получаетеInteger
сvalueOf
правой стороны, конечно.После преобразования вы сравниваете два примитивных
int
значения. Сравнение происходит так же, как вы ожидаете, что касается примитивов, поэтому вы сравниваете128
и128
.источник
List
. Другой - примитив, который является просто необработанным значением.==
. во всяком случае, теперь ясно.Integer
Класс имеет статический кэш, который хранит 256 специальныхInteger
объектов - по одному для каждого значения между -128 и 127. Имея это в виду, рассмотрим разницу между этими тремя.Это (очевидно) делает совершенно новый
Integer
объект.Это возвращает
int
примитивное значение после анализаString
.Это сложнее, чем другие. Это начинается с разбора
String
. Затем, если значение находится в диапазоне от -128 до 127, он возвращает соответствующий объект из статического кэша. Если значение находится за пределами этого диапазона, оно вызываетnew Integer()
и передает значение, чтобы вы получили новый объект.Теперь рассмотрим три выражения в вопросе.
Это возвращает true, потому что
Integer
значение, равное 127, извлекается дважды из статического кэша и сравнивается с самим собой. ЗдесьInteger
задействован только один объект, поэтому он возвращаетсяtrue
.Это возвращает
false
, потому что 128 не находится в статическом кэше. Таким образом, новоеInteger
создается для каждой стороны равенства. Так как есть два разныхInteger
объекта, и==
для объектов возвращается, толькоtrue
если обе стороны - один и тот же объект, это будетfalse
.Это сравнивает примитивное
int
значение 128 слева с вновь созданнымInteger
объектом справа. Но поскольку нет смысла сравнивать иint
сInteger
, Java будет автоматически распаковывать ихInteger
перед выполнением сравнения; так что в итоге вы сравниваетеint
сint
. Поскольку примитив 128 равен самому себе, это возвращаетсяtrue
.источник
Позаботьтесь о возврате значений из этих методов. Метод valueOf возвращает экземпляр Integer:
Метод parseInt возвращает целочисленное значение (тип примитива):
Объяснение для сравнения:
В вашей ситуации (согласно вышеуказанным правилам):
Это выражение сравнивает ссылки на один и тот же объект, поскольку оно содержит значение Integer в диапазоне от -128 до 127, поэтому оно возвращает
true
.Это выражение сравнивает ссылки на разные объекты, поскольку они содержат целочисленные значения, отсутствующие в <-128, 127>, поэтому оно возвращает
false
.Это выражение сравнивает значение примитива (левая сторона) и ссылку на объект (правая сторона), поэтому правая часть будет развернута, а его тип примитива будет сравнен с левым, поэтому он вернется
true
.источник
==
, потому что это разные объекты.Кэши целых объектов между -128 и 127 из 256 Integer
Вы не должны сравнивать ссылки на объекты с == или ! = . Вы должны использовать. равен (..) вместо этого или лучше - используйте примитив int, а не Integer.
parseInt : анализирует строковый аргумент как десятичное целое число со знаком. Все символы в строке должны быть десятичными цифрами, за исключением того, что первый символ может быть знаком минус ASCII '-' ('\ u002D') для обозначения отрицательного значения. Полученное целочисленное значение возвращается точно так, как если бы аргумент и основание 10 были заданы в качестве аргументов метода parseInt (java.lang.String, int).
Возвращает объект Integer, содержащий значение, извлеченное из указанной строки при анализе с основанием, заданным вторым аргументом. Первый аргумент интерпретируется как представляющий целое число со знаком в основании, заданном вторым аргументом, точно так же, как если бы аргументы были переданы методу parseInt (java.lang.String, int). Результатом является объект Integer, представляющий целочисленное значение, указанное в строке.
эквивалентно
radix - основа, которая будет использоваться при интерпретации
так что если вы равны
Integer.valueOf()
для целого числа междуОт -128 до 127 возвращает истину в вашем состоянии
для
lesser than
-128 иgreater than
127 это даетfalse
источник
Чтобы дополнить данные ответы, также обратите внимание на следующее:
Этот код также напечатает:
false
Как заявил пользователь Jay в комментарии о принятом ответе, необходимо соблюдать осторожность при использовании оператора
==
над объектами, здесь вы проверяете, являются ли обе ссылки одинаковыми, а это не так, потому что это разные объекты, хотя они представляют такое же значение. Чтобы сравнивать объекты, вы должны использоватьequals
вместо этого метод:Это напечатает:
true
Вы спросите: а зачем тогда печатать первую строку
true
? , Проверяя исходный кодInteger.valueOf
метода, вы можете увидеть следующее:Если параметр является целым числом между
IntegerCache.low
(по умолчанию -128) иIntegerCache.high
(вычисляется во время выполнения с минимальным значением 127), то возвращается предварительно выделенный (кэшированный) объект. Поэтому, когда вы используете 127 в качестве параметра, вы получаете две ссылки на один и тот же кэшированный объект иtrue
сравниваете ссылки.источник