Автоупаковка і розпакування в java
Автоупаковка і розпакування в Java.
У цій статті ми розглянемо таку функцію в Java як автоупаковка / розпакування.
Автоупаковка і розпакування це функція перетворення примітивних типів в об'єктні і навпаки.
Весь процес виконується автоматично середовищем виконання Java (JRE). Але слід бути обережним при реалізації цієї функції, тому що Вона може впливати на продуктивність вашої програми.
У версіях нижче JDK 1.5 було нелегко перетворювати примітивні типи даних, такі як
int, char, float, double в їх класи оболонки Integer, Character, Float, Double. Починаючи з версії JDK 5 ця функція, перетворення примітивних типів в еквівалентні об'єкти, реалізована автоматично.
Це властивість відомо як Автоупаковка (Autoboxing). Зворотний процес відповідно - Розпакування (Unboxing) тобто процес перетворення об'єктів до відповідних їм примітивні типи.
Приклад коду для автоупаковкі і розпакування представлений нижче:
Коли використовується автоупаковка і розпакування?
Автоупаковка застосовується компілятором Java в наступних умовах:
Коли значення примітивного типу передається в метод в якості параметра методу, який очікує об'єкт відповідного класу-оболонки.
Коли значення примітивного типу присвоюється змінної, відповідного класу оболонки.
Розглянемо наступний приклад:
Лістинг 1: Простий код, який показує автоупаковку
До версії jdk 1.5 наведений вище код викликав би помилку компіляції, так як оператор отримання залишку% і унарний плюс + = не могли застосовуватися до класу-оболонці.
Але в jdk 1.5 і вище цей код компілюється без помилок, перетворюючи Integer в int.
Розпакування застосовується компілятором Java в наступних умовах:
Коли об'єкт передається в якості параметра методу, який очікує відповідний примітивний тип.
Коли об'єкт присвоюється змінної відповідного примітивного типу.
Розглянемо наступний приклад:
Лістинг 2: Простий код, який показує розпакування
Автоупаковка і розпакування дозволяють розробнику писати код, який легко Новомосковскется і зрозумілий. Наступна таблиця показує примітивні типи даних і їх відповідні об'єкти оболонки.
Таблиця 1: Примітивні типи і еквівалентні їм класи оболонки
З операторами порівняння
Автоупаковка і розпакування можуть використовуватися з операторами порівняння. Наступний фрагмент коду ілюструє, як це відбувається:
Лістинг 3: Приклад коду, який показує автоупаковку і розпакування з оператором порівняння
Автоупаковка і розпакування при перевантаженні методу
Автоупаковка і розпакування виконується при перевантаженні методу на підставі наступних правил:
- Розширення «перемагає» упаковку - У ситуації, коли стає вибір між розширенням і упаковкою, розширення краще.
Лістинг 4: Приклад коду, що показує перевагу перевантаження
Висновок програми - тип int
- Розширення перемагає змінну кількість аргументів - У ситуації, коли стає вибір між розширенням і змінним кількістю аргументів, розширення краще.
Лістинг 5: Приклад коду, що показує перевагу перевантаження
- Упаковка перемагає змінну кількість аргументів - У ситуації, коли стає вибір між упаковкою і змінним кількістю аргументів, упаковка краще.
Лістинг 6: Приклад коду, що показує перевагу перевантаження
Ви повинні пам'ятати про наступні речі, використовуючи Автоупаковку:
Як ми знаємо, будь-яка хороша функція має недолік. Автоупаковка не є винятком в цьому відношенні. Деякий важливі зауваження, які повинен враховувати розробник при використанні цієї функції:
- Порівнюючи об'єкти оператором '==' може виникнути плутанина, так як він може застосовуватися до примітивних типів і об'єктів. Коли цей оператор застосовується до об'єктів, він фактично зрівнює посилання на об'єкти а не самі об'єкти.
Лістинг 7: Приклад коду, що показує порівняння.
- Змішування об'єктів і примітивних типів з оператором рівності і відносини. Якщо ми порівнюємо примітивний тип з об'єктом, то відбувається розпакування об'єкта, який може кинути NullPointerException якщо об'єкт null.
- Кешування об'єктів. Метод valueOf () створює контейнер примітивних об'єктів, які він кешируєт. Оскільки значення кешуються в діапазоні від -128 до 127 включно, ці кешувального об'єкти можуть поводитися по-різному.
- Погіршення продуктивності. Автоупаковка або розпакування погіршують продуктивність програми, оскільки це створює небажаний об'єкт, через який збирачеві сміття доводиться працювати частіше.
Недоліки Автоупаковкі.
Хоча Автоупаковка має ряд переваг, вона має такі недоліки:
Лістинг 8: Приклад коду, який показує проблему продуктивності.
У цій ділянці коду, sum + = i буде розширено на sum = sum + i. Починаючи з оператора '+' JVM запускає розпакування, так як оператор '+' не може застосовуватися до об'єкта Integer. А потім результат автоупаковивается назад.
До версії JDK 1.5 типи даних int і Integer розрізнялися. У разі перевантаження методу ці два типи використовувалися без проблем. З поява автоматичної упаковки / розпаковування це стало складніше.
Прикладом цього є перевантажений метод remove () в ArrayList. Клас ArrayList має два методи видалення - remove (index) і remove (object). В цьому випадку перевантаження методів не відбудеться і відповідний метод буде викликатися з відповідними параметрами.
Висновок.
Автоупаковка є механізмом для прихованого перетворення примітивних типів даних у відповідні класи-оболонки (об'єкти). Компілятор використовує метод valueOf () щоб перетворити примітивні типи в об'єкти, а методи IntValue (), doubleValue () і т.д. щоб отримати примітивні типи об'єкта. Автоупаковка перетворює логічний тип boolean в Boolean, byte в Byte, char в Character, float в Float, int в Integer, long в Long, short в Short. Розпакування відбувається в зворотному напрямку.
оригінал статті