IntegerКласс имеет статический кэш, который хранит 256 специальных Integerобъектов - по одному для каждого значения между -128 и 127. Имея это в виду, рассмотрим разницу между этими тремя.
new Integer(123);
Это (очевидно) делает совершенно новый Integer объект.
Integer.parseInt("123");
Это возвращает int примитивное значение после анализа String.
Integer.valueOf("123");
Это сложнее, чем другие. Это начинается с разбора String. Затем, если значение находится в диапазоне от -128 до 127, он возвращает соответствующий объект из статического кэша. Если значение находится за пределами этого диапазона, оно вызывает new Integer()и передает значение, чтобы вы получили новый объект.
Теперь рассмотрим три выражения в вопросе.
Integer.valueOf("127")==Integer.valueOf("127");
Это возвращает true, потому что Integerзначение, равное 127, извлекается дважды из статического кэша и сравнивается с самим собой. Здесь Integerзадействован только один объект, поэтому он возвращается true.
Integer.valueOf("128")==Integer.valueOf("128");
Это возвращает false, потому что 128 не находится в статическом кэше. Таким образом, новое Integerсоздается для каждой стороны равенства. Так как есть два разных Integerобъекта, и ==для объектов возвращается, только trueесли обе стороны - один и тот же объект, это будет false.
Integer.parseInt("128")==Integer.valueOf("128");
Это сравнивает примитивное intзначение 128 слева с вновь созданным Integerобъектом справа. Но поскольку нет смысла сравнивать и intс Integer, Java будет автоматически распаковывать их Integerперед выполнением сравнения; так что в итоге вы сравниваете intс int. Поскольку примитив 128 равен самому себе, это возвращается true.
.equals(), иначе все ставки выключены.