1. Список типів-обгорток

Всі ви знаєте, що Java має 8 примітивних типів, які не є класами. З одного боку, це добре: вони прості та займають мало місця, а з іншого — іноді потрібні саме класи. Навіщо саме вони, ви дізнаєтесь у наступній лекції.

То що робити?

Починаючи з п’ятої версії, в Java у примітивних типів з’явилися класи-близнюки. Кожен такий клас зберігає всередині одне поле із значенням певного типу. Такі класи ще називають типами-обгортками, тому що вони ніби перетворюють примітивні значення в класи.

Ось список таких типів, нічого не впізнаєте?

Примітивний тип Клас-обгортка
byte
Byte
short
Short
int
Integer
long
Long
float
Float
double
Double
char
Character
boolean
Boolean

Назви примітивних типів пишуться з маленької літери, а класів — із великої. Також назви класів трохи довші: Integer замість int і Character замість char.

Усі об’єкти класів-обгорток є незмінними (immutable).

Спрощений код класу Integer має приблизно такий вид:

Код Примітка
public class Integer
{
   private int value;

   Integer(int x)
   {
      this.value = x;
   }

   public int intValue()
   {
      return this.value;
   }

   public static Integer valueOf(int x)
   {
      return new Integer(x);
   }
}


Змінна-значення

Конструктор




Метод повертає значення




Статичний метод створює новий об’єкт Integer для змінної типу int

2. Перетворення типу int до Integer

Типи-обгортки вважаються аналогами їх більш примітивних побратимів: можна легко створити відповідний об’єкт-обгортку для примітивного типу.

Розберемо взаємодію примітивних типів та їх типів-обгорток на прикладі типу int. Ось який би мав вигляд код перетворення типу int до типу Integer і навпаки:

Щоб перетворити тип int до типу Integer, потрібно написати код:

Integer ім’я = new Integer(значення);

де ім’я — це ім’я змінної типу Integer, а значення — це значення типу int, що перетворюється.

Приклади:

Код Примітка
Integer age = new Integer(18);
Integer hundred = new Integer(100);
Integer zero = new Integer(0);

А щоб перетворити тип Integer до типу int, потрібно написати код:

int ім’я = змінна.intValue();

де ім’я — це ім’я змінної типу int, а змінна — це змінна-посилання на об’єкт типу Integer.

Приклади:

Код Примітка
Integer age = new Integer(18);
int x = age.intValue();

x == 18
Integer hundred = new Integer(100);
int y = hundred.intValue();

y == 100
Integer zero = new Integer(0);
int z = zero.intValue();


z == 0
int i = 110;
Integer zero = new Integer(i);
int z = zero.intValue();

z == 110

3. Autoboxing i unboxing

Проте навіть прості операції із типом Integer писати непросто.

Як ми говорили, тип Integer — незмінний (immutable). Щоб створити об’єкт типу Integer із новим значенням типу int, потрібно явно створити новий об’єкт Integer. Проте отримати значення типу int, яке зберігається всередині об’єкта Integer, просто: потрібно викликати метод intValue().

Пример:

Код Опис
Integer a = Integer.valueOf(5);
int b = a.intValue();
Integer c = new Integer(b + 5)
Перетворюємо 5 у клас Integer
Отримуємо значення з об’єкта Integer
Створюємо нове значення Integer == 10

Код досить громіздкий, не вважаєте?

Розробники Java теж так вважають, тому вони навчили компілятор робити ці операції автоматично. Автоматичне перетворення int в Integer називається autoboxing (box — коробка, класти в коробку), а зворотна операція — Integer до intunboxing.

Ваш код Що бачить компілятор
Integer a = 10;
Integer a = Integer.valueOf(10);
int b = a;
int b = a.intValue();
Integer c = a + b;
Integer c = Integer.valueOf(a.intValue() + b);

Завдяки autoboxing та unboxing ви можете спокійно присвоювати тип int типу Integer і навпаки. Можна писати вираз будь-якої складності і не робити відмінностей між типами int і Integer.

Приклади:

Код Що згенерує компілятор
Integer a = 5;
int b = a;
Integer c = a + b;
int d = a + b + c;
Integer a = Integer.valueOf(5);
int b = a.intValue();
Integer c = Integer.valueOf(a.intValue() + b);
int d = a.intValue() + b + c.intValue();
Integer a = 5;
int b = 5;

if (a == b)
{
   ...
}
Integer a = Integer.valueOf (5);
int b = 5;

if (a.intValue() == b)
{
   ...
}


4. Порівняння змінних класів-обгорток

Autoboxing і unboxing працюють дуже просто і прозоро: де потрібно — розставляються команди new Integer(), де потрібно — викликаються методи intValue().

Для вас як для програміста все працює легко та зрозуміло. Але врахуйте, якщо ви порівнюєте Integer і Integer, відбувається порівняння посилань, а чи не значень.

Код Виведення на екран
Integer a = 1000;
Integer b = 1000;

System.out.println(a == b);



false
Integer a = 1000;
Integer b = 1000;

System.out.println(a.equals(b));



true

Змінні a і b зберігають не значення (як типи int), а посилання на об’єкти. Тому важливо пам’ятати, як правильно їх порівнювати:

Неправильно Правильно
Integer a = 1000;
Integer b = 1000;
if (a == b)
{
   ...
}
Integer a = 1000;
Integer b = 1000;
if (a.equals(b))
{
   ...
}