Опаковъчни класове в Java

1. Общ преглед

Както подсказва името, класовете обвивки са обекти, капсулиращи примитивни типове Java.

Всеки примитив на Java има съответна обвивка:

  • boolean, byte, short, char, int, long, float, double
  • Boolean, Byte, Short, Character, Integer, Long, Float, Double

Всички те са дефинирани в пакета java.lang , поради което не е необходимо да ги импортираме ръчно.

2. Класове на обвивки

„Каква е целта на клас на обвивка?“. Това е един от най-често срещаните въпроси за интервю за Java.

По принцип общите класове работят само с обекти и не поддържат примитиви . В резултат на това, ако искаме да работим с тях, трябва да преобразуваме примитивни стойности в обекти с обвивка.

Например, Java Collection Framework работи изключително с обекти. Отдавна, когато (преди Java 5, почти 15 години назад) не е имало автобокс и ние, например, не можехме просто да извикаме add (5) в колекция от Integers.

По това време тези примитивни стойности трябваше да се преобразуват ръчно в съответните класове на обвивки и да се съхраняват в колекции.

Днес, с autoboxing, ние можем лесно да направим ArrayList.add (101) , но вътрешно Java преобразува примитивна стойност до цяло число , преди да я съхранявате в ArrayList с помощта на valueOf () метод .

3. Преобразуване на примитивен клас на обвивка

Сега големият въпрос е: как да преобразуваме примитивна стойност в съответния клас на обвивка, например int в Integer или char в Character?

Е, можем да използваме конструктор или статични фабрични методи за преобразуване на примитивна стойност в обект от клас на обвивка.

От Java 9 обаче конструкторите за много примитиви в кутия като Integer или Long са оттеглени.

Така че е силно препоръчително да използвате фабричните методи само за нов код .

Нека да видим пример за преобразуване на int стойност в Integer обект в Java:

Integer object = new Integer(1); Integer anotherObject = Integer.valueOf(1);

Методът valueOf () връща екземпляр, представляващ посочената стойност int .

Той връща кеширани стойности, което го прави ефективен. Той винаги кешира стойности между -128 и 127, но може да кешира и други стойности извън този диапазон.

По същия начин можем също да преобразуваме булево в булево, байт в байт, char в символ, дълго в дълго, плаващо в плаващо и двойно в двойно. Въпреки че ако трябва да конвертираме String в Integer, трябва да използваме метода parseInt () , защото String не е клас на обвивка.

От друга страна, за да преобразуваме от обект-обвивка в примитивна стойност, можем да използваме съответния метод като intValue (), doubleValue () и т.н.:

int val = object.intValue(); 

Изчерпателна справка можете да намерите тук.

4. Autoboxing и Unboxing

В предишния раздел показахме как ръчно да конвертирате примитивна стойност в обект.

След Java 5 това преобразуване може да се извърши автоматично, като се използват функции, наречени автобокс и дебоксиране.

„Бокс“ се отнася до преобразуване на примитивна стойност в съответния обект на обвивка. Тъй като това може да се случи автоматично, това е известно като автобокс.

По подобен начин, когато обект-обвивка се разгъне в примитивна стойност, това е известно като разопаковане.

Това на практика означава, че можем да предадем примитивна стойност на метод, който очаква обект-обвивкаили да присвоите примитив на променлива, която очаква обект:

List list = new ArrayList(); list.add(1); // autoboxing Integer val = 2; // autoboxing

В този пример Java автоматично ще преобразува примитивната стойност int в обвивката.

Вътрешно използва метода valueOf () , за да улесни преобразуването. Например следните редове са еквивалентни:

Integer value = 3; Integer value = Integer.valueOf(3);

Въпреки че това прави конвертирането лесно и кодовете по-четливи, има някои случаи, в които не бива да използваме автобокс, например в цикъл .

Подобно на автоматичното опаковане, освобождаването се извършва автоматично при предаване на обект на метод, който очаква примитив или когато го присвоите на примитивна променлива:

Integer object = new Integer(1); int val1 = getSquareValue(object); //unboxing int val2 = object; //unboxing public static int getSquareValue(int i) { return i*i; }

По принцип, ако напишем метод, който приема примитивна стойност или обект на обвивка, все пак можем да им предадем и двете стойности. Java ще се погрижи да предаде правилния тип, напр. Примитив или обвивка, в зависимост от контекста.

5. Заключение

В този бърз урок говорихме за класове на обвивки в Java, както и за механизма на автобоксиране и разопаковане.