Чтобы объяснить, почему код печатает такой вывод, нам, возможно, придется взглянуть на более низкий уровень:
Я декомпилировал ваш код до уровня байт-кода.
Для 1-й строки:
System.out.println((Integer.valueOf("5000") <= Integer.valueOf("5000")));
Байт-код (бесполезная информация удалена):
LDC "5000"
INVOKESTATIC java/lang/Integer.valueOf (Ljava/lang/String;)Ljava/lang/Integer;
INVOKEVIRTUAL java/lang/Integer.intValue ()I
LDC "5000"
INVOKESTATIC java/lang/Integer.valueOf (Ljava/lang/String;)Ljava/lang/Integer;
INVOKEVIRTUAL java/lang/Integer.intValue ()I
IF_ICMPGT L1
Вы можете увидеть для левой части из <=
, JVM использует функцию Integer.valueOf для преобразования строки в объект типа Integer. Затем используйте функцию Integer.intValue, чтобы извлечь внутреннее значение этого объекта (также , называемое автоматическим распаковыванием ). Итак, для левой части мы получаем значение int
.
Правая часть <=
такая же, как левая часть.
Последняя строка IF_ICMPGT
, для сравнения этих двух значений int. Итак, вывод таков: если вы используете <=
, компилятор Java сделает для вас автоматическую распаковку и сравнит внутренние значения int.
Для 2-й строки:
System.out.println((Integer.valueOf("5000") == Integer.valueOf("5000")));
Байт-код (бесполезная информация удаляется):
LDC "5000"
INVOKESTATIC java/lang/Integer.valueOf (Ljava/lang/String;)Ljava/lang/Integer;
LDC "5000"
INVOKESTATIC java/lang/Integer.valueOf (Ljava/lang/String;)Ljava/lang/Integer;
IF_ACMPNE L4
Вы видите, что байт-код отличается от 1-й строки. Он просто конвертирует строки в целочисленные объекты, но НЕ автоматически распаковывает их. А поскольку они представляют собой два отдельных объекта, они должны иметь разные адреса (в памяти).
Последняя строка IF_ACMPNE
будет сравнивать адреса этих двух целочисленных объектов. Итак, вывод таков: если вы используете ==
, компилятор Java не сделает автоматическую распаковку для вас и сравнит адреса объектов.
Что еще
Класс Integer
кэширует Целочисленные объекты для диапазона -128 ~ 127. Это означает, что если вы передадите строку с этим диапазоном, вы получите точно такой же объект Integer. Ниже код напечатает true:
System.out.println((Integer.valueOf("127") == Integer.valueOf("127"))); // true