JavaRush /Курси /JAVA 25 SELF /Типи-обгортки в Java

Типи-обгортки в Java

JAVA 25 SELF
Рівень 10 , Лекція 1
Відкрита

1. Вступ

У мові Java існує два сімейства даних. Перше — це примітивні типи: int, char, double, boolean та інші. Вони прості й швидкі: у них значення зберігається безпосередньо в комірці памʼяті. Друге сімейство — це посилальні типи, тобто обʼєкти: змінна містить посилання на місце в памʼяті, де розташовано обʼєкт.

Іноді потрібно використати примітив як обʼєкт, проте примітиви від початку не є обʼєктами. У таких випадках допомагають спеціальні класи-обгортки.

Типи-обгортки — це класи, що всередині тримають значення примітиву та дають змогу працювати з ним як із обʼєктом. Наприклад, для int — клас Integer, для doubleDouble, для charCharacter, для booleanBoolean. Такі класи надають методи, зокрема: Integer.parseInt(), Double.isInfinite(), Character.isLetter(), Boolean.parseBoolean() тощо.

Приклад отримання обʼєкта Integer з примітива int:

// примітив
int a = 10;

// обʼєкт-обгортка
Integer b = Integer.valueOf(10);

У змінній a зберігається саме число 10, а в змінній b — посилання на обʼєкт, що всередині містить 10.

2. Навіщо потрібні обгортки

Примітивне значення не може дорівнювати null. Натомість посилання на обʼєкт може бути порожнім — null. Це зручно, коли треба позначити «невідомо» або «немає».

У примітивів немає методів. Не можна викликати для числа, наприклад, x.toString(). Обгортка дає такі можливості: Integer.parseInt("123") перетворює рядок на число, а число можна перетворити на рядок за допомогою toString().

Висновок: обгортки потрібні там, де потрібен саме обʼєкт — можливість зберігати null, викликати методи, передавати значення в API, що приймає лише обʼєкти (наприклад, колекції на кшталт List<Integer>).

Повний список типів-обгорток

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

3. Пакування та розпакування

Коли ви вручну створюєте обʼєкт-обгортку, берете примітив і «пакуєте» його всередину обʼєкта:

int primitive = 42;
Integer wrapper = Integer.valueOf(primitive); // пакування

Щоб знову отримати примітивне значення — «розпакувати» — використовують, наприклад, intValue():

Integer wrapper = Integer.valueOf(42);
int primitive = wrapper.intValue(); // розпакування

Автобоксинг (Autoboxing)

Компілятор автоматично додасть виклик valueOf(), якщо ви присвоюєте примітив змінній-обгортці:

int a = 10;
Integer b = a; // автобоксинг (Integer.valueOf(a))

Анбоксинг (Unboxing)

Зворотна ситуація — коли обʼєкт-обгортка використовується там, де потрібен примітив:

Integer c = 20;
int d = c; // анбоксинг (c.intValue())

int a = 10; // примітив
Integer b = a; // автобоксинг
Integer c = Integer.valueOf(20);
int d = c; // анбоксинг
Автобоксинг та анбоксинг

4. Підводні камені

Порівняння обгорток. Оператор == для обʼєктів порівнює посилання, а не значення:

Integer m = 200;
Integer n = 200;
System.out.println(m == n); // false, бо це різні обʼєкти

Java кешує обʼєкти-обгортки чисел у діапазоні від -128 до 127, тож інколи == поверне true, а інколи — false. Для порівняння значень завжди використовуйте equals():

Integer x = 100;
Integer y = 100;
System.out.println(x == y);      // true, потрапили в кеш
System.out.println(x.equals(y)); // true, порівняння за значенням

NullPointerException під час анбоксингу. Якщо обʼєкт-обгортка дорівнює null, а ви намагаєтеся її розпакувати — отримаєте виняток:

Integer value = null;
int primitive = value; // Помилка! NullPointerException

Продуктивність і памʼять. Обгортки повільніші за примітиви й займають більше памʼяті. У «гарячих» ділянках коду та під час роботи з великими масивами чисел обирайте примітиви.

5. Приклади

Приклади роботи з Integer і Double

Перетворення рядка на число:

String text = "123";
int number = Integer.parseInt(text);
System.out.println(number); // 123

Перевірка спеціальних значень дійсних чисел:

double d = 1.0 / 0;
System.out.println(Double.isInfinite(d)); // true

double nan = 0.0 / 0.0;
System.out.println(Double.isNaN(nan)); // true

Приклади роботи з Character

char зберігає один символ; обгортка Character дає зручні перевірки:

char ch = 'A';
Character wrapper = ch; // автобоксинг

System.out.println(Character.isLetter(ch)); // true
System.out.println(Character.isDigit(ch));  // false
System.out.println(Character.toLowerCase(ch)); // 'a'

Приклади роботи з Boolean

Примітив boolean — це тільки true/false. Обгортка Boolean дозволяє зберігати ще й null:

Boolean flag = null; // припустимо
flag = Boolean.TRUE; // спеціальна константа

System.out.println(flag); // true

Перетворення рядків у логічні значення:

String s1 = "true";
String s2 = "false";
boolean b1 = Boolean.parseBoolean(s1);
boolean b2 = Boolean.parseBoolean(s2);

System.out.println(b1); // true
System.out.println(b2); // false
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ