JavaRush /Java блог /Random UA /Рівень 29. Відповіді на запитання до співбесіди на тему р...
DefNeo
36 рівень

Рівень 29. Відповіді на запитання до співбесіди на тему рівня

Стаття з групи Random UA
Рівень 29. Відповіді на запитання до співбесіди на тему рівня - 1
  1. Що таке autoboxing?

    Автоупаковка - це механізм неявної ініціалізації об'єктів класів-оберток (Byte, Short, Character, Integer, byteLong , Float , Double) значеннями відповідних ним вихідних примітивних типів (відповід.,,,,,,,,), без явного використання конструктора класу .shortcharintlongfloatdouble

    Автоупаковка відбувається при прямому присвоєння примітиву - класу-обгортці (за допомогою оператора " ="), або при передачі примітиву в параметри методу (типу "класу-обгортки"). Автопакування в "класи-обертки" можуть бути піддані як змінні примітивних типів, так і константи часу компіляції (літерали та final-примітиви). При цьому літерали мають бути синтаксично коректними для ініціалізації змінної вихідного примітивного типу.

    Автоупаковка змінних примітивних типів вимагає точної відповідності типу вихідного примітиву - типу "класу-обгортки". Наприклад, спроба автоупакувати змінну типу byteв Shortбез попереднього явного приведення byte->shortвикликає помилку компіляції.

    Автоупаковка констант примітивних типів допускає ширші межі відповідності. У цьому випадку компілятор здатний попередньо здійснювати неявне розширення/звуження типу примітивів. Перетворення відбувається у два етапи:

    1. неявне розширення (звуження) вихідного типу примітиву до типу примітиву відповідного класу-обертці (для перетворення int->Byte, спочатку компілятор неявно звужує intв byte)

    2. автоупаковку примітиву у відповідний "клас-обгортку" (компілятор автоупаковує byte->Byte). однак у цьому випадку існують два додаткові обмеження:

      • присвоєння примітиву - "обертці" може здійснюватися тільки оператором " =" (не можна передати такий примітив у параметри методу, без явного приведення типів)

      • тип лівого операнда повинен бути старше ніж Character, тип правого не дожен старше int, (припустимо розширення/звуження byte <-> short, byte <-> char, short <-> char
        і лише звуження byte <- int, short <- int, char <- int, інші варіанти вимагають явного приведення типів)

    Додаткова особливість цілих "класів-оберток" створених автоупаковкою констант в діапазоні -128 +127 , в те що вони кешуються JVM. Тому такі обгортки з однаковими значеннями будуть посилання на один об'єкт.

  2. Навіщо використовується autoboxing?

    Я процитую лекцію:

    Наскільки ти пам'ятаєш, Java є як типи, успадковані від класу Object, так і примітивні типи. Але, як виявилося, така зручна річ як колекції та generic'и можуть працювати тільки з типами, успадкованими від Object.

  3. Альтернативи autoboxing?

    Не знайшов відповіді, але застиг на StackOverFlow .

    Виходячи з цієї дискусії, виходить, що альтернатива autoboxingце використання примітивних типів, так як використання autoboxingзнижує продуктивність. Висновок: використовувати autoboxingтільки там, де це необхідно.

    Написано статтю про Autoboxing: Autoboxing: Traps and Advantages

  4. Типи-обертки для примітивних типів mutableабо immutable?

    Immutable, оскільки примітивні об'єкти також immutable. Щоб працювати з Mutableтипом є клас MutableInteger, і.т.д.

  5. Як примітивні типи наводяться до непримітивних аналогів?

    На це та наступне питання добре відповідає ось ця стаття: Автоупаковка та розпакування в Java

    Це висновок з неї: автоупаковка є механізмом прихованого перетворення примітивних типів даних у відповідні класи-оболонки (об'єкти). Компілятор використовує метод, valueOf()щоб перетворити примітивні типи на об'єкти, а методи IntValue(), doubleValue()і т.д., щоб отримати примітивні типи з об'єкта (тобто зворотне перетворення). Автоупаковка перетворює логічний тип booleanв Boolean, byteв Byte, charв Character, floatв Float, intв Integer, longв Long, shortв Short. Розпакування відбувається у зворотному напрямку.

  6. Як непримітивні типи наводяться до примітивних?

    Вище відповів.

  7. Як порівнюються примітивні та непримітивні типи?

    У лекції це докладно розглядається, але я знайшов так скажемо те саме, але іншими словами.

    У Java є два способи порівнювати об'єкти на рівність ==і метод equals().

    ==використовується примітивних типів. Для об'єктів « ==» це виключно порівняння посилань. Для решти випадків потрібно використовувати метод equals(). Крім того, метод hashCode()служить (теоретично) для тієї ж мети. Хорошим тоном вважається, якщо ви перевизначабо equals()та hashCode(). Після ініціалізації деяких об'єктів a і b має виконуватися правило:

    Якщо вираз a.equals(b)поверне true , то a.hashCode()повинен дорівнювати b.hashCode().

  8. Чи завжди створюється новий об'єкт під час операції autoboxing?

    Це у лекціях є:

    Коли ми присвоюємо змінної типу Integer значення типу int, у своїй викликається метод Integer.valueOf: функція який valueOfзавжди створює новий об'єкт типу Integer. Вона кешує значення від -128 до 127.

    Якщо значення, що передається, виходить за ці межі, то новий об'єкт створюється, а якщо ні, то ні.

    Якщо ми пишемо new Integer(), то гарантовано створюється новий об'єкт. Якщо ми викликаємо Integer.valueOf(), явно чи при autoboxing, цей метод може повернути нам як новий об'єкт, і віддати об'єкт з кешу, якщо передане число лежить у діапазоні від -128 до 127.

  9. Як працює кешування при операції autoboxing?

    Відповів у питанні вище, про всяк випадок створив питання на StackOverFlow , але там відповідають те саме

  10. Для яких типів та/або значень працює кешування?

    У восьмому питанні. Якщо у когось – тобто міркування на тему трьох останніх питань, то напишіть у коментарях.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ