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, както и за механизма на автобоксиране и разопаковане.