JavaRush /Курси /Java Syntax Zero /Класи-обгортки в Java

Класи-обгортки в Java

Java Syntax Zero
Рівень 13 , Лекція 1
Відкрита

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 та 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))
{
   ...
}

Коментарі (22)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
RMykola Рівень 20
27 лютого 2025
Лекція, як на мене, середнього рівня важкості. Задачі усі окрім останньої вдалось вирішити з першої спроби. На останній затупив, і використовував в рішенні не метод equals(), а метод intValue(). Просто неуважно прочитав умови задачі.
nveenespi Рівень 2
20 липня 2024
Мені здається треба прояснити чому розробники java не могли забити на примітиви і використовувати всюди врапери. Відповідь на скріншоті :)
Christopher Ward 595 Рівень 16
3 серпня 2024
Дякую, друже!
Гаркін Рівень 14
14 травня 2024
Додайте ;

Integer c = new Integer(b + 5)
Ян Третьяк Рівень 29
10 січня 2024
Може в когось як і в мене виникало таке питання: Integer a = Integer.valueOf(5); В цьому випадку, a - це об'єкт типу Integer, який представляє число 5. Integer а= new Integer(5); Тут використовується конструктор Integer(int), який теж створює об'єкт типу Integer. Проте важливо відзначити, що з Java 9 конструктор Integer(int) вважається застарілим, і рекомендується використовувати метод valueOf через конструктор. Отже, основна різниця полягає в тому, що valueOf може використовувати кешовані значення для невеликих чисел (від -128 до 127), що може покращити продуктивність, оскільки може повертати існуючий об'єкт, якщо відомо, що такий об'єкт вже існує в кеші. Конструктор Integer(int), навпаки, завжди створює новий об'єкт. Отже, рекомендується використовувати valueOf для отримання ефективності та для уникнення використання застарілого конструктора.
Андрій Рівень 18
15 січня 2024
Дякую за пояснення🙃
Pavlo Kezin Рівень 23
4 вересня 2023
якість лекції жахлива. як працює майже зрозуміло, а навіщо не відомо.
Serhii Nahryshko Рівень 14
15 лютого 2023
Останню задачу вирішив взагалі без методу equals(), натомість використав числове порівняння first.intValue()==second.intValue() і тим сами воконав умови задачі №3 (Додай використання методу equals() мінімальну кількість разів.) Нажаль, компілятор лається 😭
Roma Chernesh Рівень 16
20 січня 2023
Той випадок, коли в теорії все звучало так логічно, а як робив задачки, то щось заплтутався і перестав розуміти:)
dianosauric Рівень 42
22 вересня 2022
Компілятор просто геніальний :)
Mykola Рівень 15 Expert
28 серпня 2023
Як ти так все швидко проходиш?
dianosauric Рівень 42
31 жовтня 2023
В мене було багато вільного часу і бажання вивчати джаву)
FAUST_ua Рівень 29
8 серпня 2022
Завдання task1201, 1202 логічно перенести і поставити після частини 3 (після саме поянення теорії, а не до).
dianosauric Рівень 42
22 вересня 2022
це така фішка для кращого запам'ятовування: спочатку мозок думає над вирішенням задачі, без попередньої теорії він ламається і потім ми або гуглимо і запам'ятовуємо це краще, або з терпінням відкладаємо задачу на трохи потім і вже потім пройшовши теорію повертаємось до задачі і краще запам'ятовуємо. Я двічі сильно сердилась "ну як це так задачі дають, а теорії потрібної для їх вирішення не було", але я навпаки тішусь такому підходу, бо впевнена, що він кращий для запам'ятовування
12 липня 2022
Для задачі "Порівняння чисел" важливо: == между двумя ссылочными типами всегда используется сравнение ссылок == между ссылочным типом и числовым примитивным типом всегда является числовое сравнение.
bodyabtc Рівень 16
2 серпня 2022
дуже дякую за відповідь, взагалі нічого не вказано в статті, важко було зрозуміти чому second == third return true, тепер зрозумів !
Beisik Рівень 25
16 листопада 2022
Дякую.Ато я задачку пройшов і зявилось питання чому так
Pavlo Kezin Рівень 23
4 вересня 2023
ось тут дякую