„Тъй като разработчиците можеха да измислят класове, които описват числа, те решиха да бъдат креативни, като истински разработчици.“

„Първо, те излязоха с абстрактен клас Number, от който се извличат Byte, Short, Integer, Long, Float и Double. Той има методи, които помагат за преобразуването на числа в други числови типове.“

Методи на клас Число
1
int intValue()
2
long longValue()
3
float floatValue()
4
double doubleValue()
5
byte byteValue()
6
short shortValue()

"Точно. В крайна сметка не можете да напишете това:"

Long x = 100000;
Integer y = (Integer) x;

"Да, тези типове не са примитивни. Ето защо използваме методите на класа Number:"

Long x = 100000;
Integer y = x.intValue();

„Но все още има няколко неща, които трябва да се вземат предвид. Тъй като Integer не е int, Integer обектите не могат да се сравняват с класическия оператор «==».

Сравняване на примитивни типове
int x = 500;
int y = 500;
x == y; //true
Сравняване на непримитивни типове
Integer x = 500;
Integer y = 500;
x == y; //false
x.equals(y); //true

— Точно така. НяHow си не се сетих за това веднага.

— Но има и още.

„Давате на късо веригите ми! Какво друго има?“

„Когато присвоим стойност int на променлива Integer, методът Integer.valueOf се извиква:“

Код Какво наистина се случва
Integer x = 5;
Integer x = Integer.valueOf(5);

„Да, вече го разбрах от горния пример.“

„Но функцията valueOf не винаги създава нов обект Integer.“

„Ъъъ, Howво имаш предвид „не винаги“?“

„Той кешира стойности от -128 до 127.“

Код Какво наистина се случва Описание
Integer x = 300;
Integer y = 300;
Integer z = 300;
Integer x = Integer.valueOf(300);
Integer y = Integer.valueOf(300);
Integer z = Integer.valueOf(300);
Променливите x, y и z съдържат препратки към различни обекти
Integer x = 100;
Integer y = 100;
Integer z = 100;
Integer x = Integer.valueOf(100);
Integer y = Integer.valueOf(100);
Integer z = Integer.valueOf(100);
Променливите x, y и z съдържат препратки към един и същ обект.
Integer x = new Integer(10)
Integer y = new Integer(10)
Integer z = 10;
Integer t = 10;
Integer x = new Integer(10)
Integer y = new Integer(10)
Integer z = Integer.valueOf(10);
Integer t = Integer.valueOf(10);
Променливите z и t съдържат препратки към един и същ обект.

"С други думи, ситуацията е следната:"

1)  Ако напишем «new Integer()», тогава гарантирано ще получим нов обект.

2)  Ако извикаме Integer.valueOf(), изрично or чрез autoboxing, тогава методът може да върне нов обект or кеширан обект, ако числовият аргумент е в диапазона от -128 до 127.

"Какво е толкова ужасно в метода, който връща обект от кеша?"

„Няма meaning. Просто трябва да знаете, че понякога, когато не го очаквате, обектите може да са равни. Всичко с equalsство е сложно. Ако сравним примитив с непримитив, тогава те се сравняват като примитиви:“

Проблем със сравнението
int x = 300;
Integer y = 300;
Integer z = 300;

x == y; //true (comparison based on primitive value)
x == z; //true (comparison based on primitive value)
y == z; //false (comparison based on references)
Още по-интересен пример. Кешът влиза в картината тук
int x = 100;
Integer y = 100;
Integer z = 100;

x == y; //true (comparison based on primitive value)
x == z; //true (comparison based on primitive value)
y == z; //true (comparison based on references; they point to the same object)
Но кешът не е включен тук
int x = 100;
Integer y = new Integer(100);
Integer z = 100;

x == y; //true (comparison based on primitive value)
x == z; //true (comparison based on primitive value)
y == z; //false (comparison based on references; they point to different objects)

— Страхотно... И How ще запомня всичко това?

„Не е нужно да запаметявате това. Просто трябва да разберете How е организирано всичко това и Howво всъщност се случва, когато в игра влязат примитивен и негов не-примитивен аналог.“

"Препоръчвам също така да разгледате методите на класа Integer. Той има доста добри и полезни методи. Вие дори сте използвали един от тях доста често."

„Да, помня. Integer.parseInt();“