-
Що таке
autoboxing
?Автоупаковка - це механізм неявної ініціалізації об'єктів класів-оберток (Byte, Short, Character, Integer,
byte
Long , Float , Double) значеннями відповідних ним вихідних примітивних типів (відповід.,,,,,,,,), без явного використання конструктора класу .short
char
int
long
float
double
Автоупаковка відбувається при прямому присвоєння примітиву - класу-обгортці (за допомогою оператора "
=
"), або при передачі примітиву в параметри методу (типу "класу-обгортки"). Автопакування в "класи-обертки" можуть бути піддані як змінні примітивних типів, так і константи часу компіляції (літерали таfinal
-примітиви). При цьому літерали мають бути синтаксично коректними для ініціалізації змінної вихідного примітивного типу.Автоупаковка змінних примітивних типів вимагає точної відповідності типу вихідного примітиву - типу "класу-обгортки". Наприклад, спроба автоупакувати змінну типу
byte
вShort
без попереднього явного приведенняbyte->short
викликає помилку компіляції.Автоупаковка констант примітивних типів допускає ширші межі відповідності. У цьому випадку компілятор здатний попередньо здійснювати неявне розширення/звуження типу примітивів. Перетворення відбувається у два етапи:
-
неявне розширення (звуження) вихідного типу примітиву до типу примітиву відповідного класу-обертці (для перетворення
int->Byte
, спочатку компілятор неявно звужуєint
вbyte
) -
автоупаковку примітиву у відповідний "клас-обгортку" (компілятор автоупаковує
byte->Byte
). однак у цьому випадку існують два додаткові обмеження: -
присвоєння примітиву - "обертці" може здійснюватися тільки оператором "
=
" (не можна передати такий примітив у параметри методу, без явного приведення типів) -
тип лівого операнда повинен бути старше ніж
Character
, тип правого не дожен старшеint
, (припустимо розширення/звуженняbyte <-> short
,byte <-> char
,short <-> char
і лише звуженняbyte <- int
,short <- int
,char <- int
, інші варіанти вимагають явного приведення типів)
Додаткова особливість цілих "класів-оберток" створених автоупаковкою констант в діапазоні -128 +127 , в те що вони кешуються JVM. Тому такі обгортки з однаковими значеннями будуть посилання на один об'єкт.
-
-
Навіщо використовується
autoboxing
?Я процитую лекцію:
Наскільки ти пам'ятаєш, Java є як типи, успадковані від класу
Object
, так і примітивні типи. Але, як виявилося, така зручна річ як колекції та generic'и можуть працювати тільки з типами, успадкованими відObject
. -
Альтернативи
autoboxing
?Не знайшов відповіді, але застиг на StackOverFlow .
Виходячи з цієї дискусії, виходить, що альтернатива
autoboxing
це використання примітивних типів, так як використанняautoboxing
знижує продуктивність. Висновок: використовуватиautoboxing
тільки там, де це необхідно.Написано статтю про
Autoboxing
: Autoboxing: Traps and Advantages -
Типи-обертки для примітивних типів
mutable
абоimmutable
?Immutable
, оскільки примітивні об'єкти такожimmutable
. Щоб працювати зMutable
типом є класMutableInteger
, і.т.д. -
Як примітивні типи наводяться до непримітивних аналогів?
На це та наступне питання добре відповідає ось ця стаття: Автоупаковка та розпакування в Java
Це висновок з неї: автоупаковка є механізмом прихованого перетворення примітивних типів даних у відповідні класи-оболонки (об'єкти). Компілятор використовує метод,
valueOf()
щоб перетворити примітивні типи на об'єкти, а методиIntValue()
,doubleValue()
і т.д., щоб отримати примітивні типи з об'єкта (тобто зворотне перетворення). Автоупаковка перетворює логічний типboolean
вBoolean
,byte
вByte
,char
вCharacter
,float
вFloat
,int
вInteger
,long
вLong
,short
вShort
. Розпакування відбувається у зворотному напрямку. -
Як непримітивні типи наводяться до примітивних?
Вище відповів.
-
Як порівнюються примітивні та непримітивні типи?
У лекції це докладно розглядається, але я знайшов так скажемо те саме, але іншими словами.
У Java є два способи порівнювати об'єкти на рівність
==
і методequals()
.==
використовується примітивних типів. Для об'єктів «==
» це виключно порівняння посилань. Для решти випадків потрібно використовувати методequals()
. Крім того, методhashCode()
служить (теоретично) для тієї ж мети. Хорошим тоном вважається, якщо ви перевизначабоequals()
таhashCode()
. Після ініціалізації деяких об'єктів a і b має виконуватися правило:Якщо вираз
a.equals(b)
поверне true , тоa.hashCode()
повинен дорівнюватиb.hashCode()
. -
Чи завжди створюється новий об'єкт під час операції
autoboxing
?Це у лекціях є:
Коли ми присвоюємо змінної типу Integer значення типу
int
, у своїй викликається методInteger.valueOf
: функція якийvalueOf
завжди створює новий об'єкт типу Integer. Вона кешує значення від -128 до 127.Якщо значення, що передається, виходить за ці межі, то новий об'єкт створюється, а якщо ні, то ні.
Якщо ми пишемо
new Integer()
, то гарантовано створюється новий об'єкт. Якщо ми викликаємоInteger.valueOf()
, явно чи приautoboxing
, цей метод може повернути нам як новий об'єкт, і віддати об'єкт з кешу, якщо передане число лежить у діапазоні від -128 до 127. -
Як працює кешування при операції
autoboxing
?Відповів у питанні вище, про всяк випадок створив питання на StackOverFlow , але там відповідають те саме
-
Для яких типів та/або значень працює кешування?
У восьмому питанні. Якщо у когось – тобто міркування на тему трьох останніх питань, то напишіть у коментарях.
DefNeo
36 рівень
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ