— Якщо розробники могли вигадувати класи, які описують числа, вони вирішили підійти до цієї справи творчо, як справжні розробники.
По-перше, вигадали абстрактний клас Number (число), від якого успадковані типи Byte, Short,Integer, Long, Float, Double. Він має методи, які допомагають перетворювати числа до інших числових типів.
Методи класу Number | |
---|---|
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
— Справді, вже не напишеш:
Long x = 100000;
Integer y = (Integer) x;
— Ага. Типи не примітивні. Тому використовують методи класу Number:
Long x = 100000;
Integer y = x.intValue();
Але тут є ще кілька моментів. Т.к. Integer – це int, то об'єкти такого типу не можна порівнювати класичним знаком «==».
int x = 500;
int y = 500;
x == y; //true
Integer x = 500;
Integer y = 500;
x == y; //false
x.equals(y); //true
— Точно. Якось я одразу про це не подумав.
— Але це ще не все.
— Господи, що ж там ще?
— Коли ми присвоюємо змінної типу Integer значення типу int, викликається метод Integer.valueOf:
Код | Що відбувається насправді |
---|---|
|
|
— Ага. Я це зрозумів ще прикладом вище.
— Так ось, функція valueOf не завжди створює новий об'єкт типу Integer.
— Тобто. як це не завжди?
— Вона кешує значення від -128 до 127.
Код | Що відбувається насправді | Опис |
---|---|---|
|
|
Всі змінні x,y,z містять посилання на різні об'єкти |
|
|
Всі змінні x,y,z містять посилання на той самий об'єкт. |
|
|
Всі змінні z,t містять посилання на той самий об'єкт. |
Тобто. ситуація така:
1) Якщо ми пишемо new Integer(), то гарантовано створюється новий об'єкт.
2) Якщо ми викликаємо Integer.valueOf(), явно або при autoboxing, то цей метод може повернути для нас як новий об'єкт, так і віддати об'єкт з кешу, якщо передане число лежить в діапазоні від -128 до 127.
— А що в цьому такого страшного, якщо метод поверне об'єкт із кешу?
— Да нічого. Просто потрібно знати, що іноді, коли цього не очікуєш, об'єкти можуть бути рівними. Там із рівністю взагалі все складно. Якщо ми порівнюємо примітивний тип і не примітивний, вони порівнюються як примітиви:
int x = 300;
Integer y = 300;
Integer z = 300;
x==y; //true (порівнюються як примітиви за значенням)
x==z; //true (порівнюються як примітиви за значенням)
y==z; //false (порівнюються за посиланням)
int x = 100;
Integer y = 100;
Integer z = 100;
x==y; //true (порівнюються як примітиви за значенням)
x==z; //true (порівнюються як примітиви за значенням)
y==z; //true (порівнюються за посиланням, посилаються на той самий об'єкт)
int x = 100;
Integer y = New Integer (100);
Integer z = 100;
x==y; //true (порівнюються як примітиви за значенням)
x==z; //true (порівнюються як примітиви за значенням)
y==z; //false (порівнюються за посиланням, посилаються на різні об'єкти)
— М-так. І як це все запам'ятати…
— Не треба це запам'ятовувати. Потрібно просто зрозуміти, як це все влаштовано і що відбувається насправді, коли в справу вступає примітивний тип та його непримітивний аналог.
Ще раджу тобі подивитися на методи класу Integer, має досить багато хороших і корисних методів. Ти навіть одним із них часто користувався.
— Ага. Пам'ятаю. Integer.parseInt();
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ