Рубрики
Без рубрики

Классы-оболочки в Java

Взгляните на классы-оболочки в Java и на то, как работают примитивы бокса и распаковки.

Автор оригинала: Paul Javin.

1. Обзор

Как следует из названия, классы-оболочки – это объекты, инкапсулирующие примитивные типы Java.

Каждый примитив Java имеет соответствующую оболочку:

  • boolean, byte, short, char, int, long, float, double
  • Логический, Байт, Короткий, Символ, Целое число, Длинный, С плавающей запятой, Двойной

Все они определены в пакете java.lang , поэтому нам не нужно импортировать их вручную.

2. Классы обертки

“Какова цель класса обертки?”. Это один из самых распространенных вопросов для интервью на Java .

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

Например, фреймворк коллекции Java работает исключительно с объектами. Давным-давно (до Java 5, почти 15 лет назад) не было автобоксов, и мы, например, не могли просто вызвать add(5) для набора целых чисел.

В то время эти примитивные значения должны были быть вручную преобразованы в соответствующие классы-оболочки и сохранены в коллекциях.

Сегодня, с помощью autoboxing, мы можем легко сделать ArrayList.add(101) но внутренне Java преобразует примитивное значение в Целое число перед сохранением его в ArrayList с помощью метода valueOf () .

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

Теперь большой вопрос: как мы преобразуем примитивное значение в соответствующий класс-оболочку, например, int в Целое число или char в Символ?

Ну, мы можем использовать либо конструкторские, либо статические фабричные методы для преобразования примитивного значения в объект класса-оболочки.

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

Поэтому настоятельно рекомендуется использовать только заводские методы в новом коде .

Давайте рассмотрим пример преобразования значения int в объект Integer в Java:

Integer object = new Integer(1);

Integer anotherObject = Integer.valueOf(1);

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

Он возвращает кэшированные значения, что делает его эффективным. Он всегда кэширует значения от -128 до 127, но также может кэшировать другие значения за пределами этого диапазона.

Аналогично, мы также можем преобразовать boolean в Boolean, byte в Byte, char в Символ, long в Long, float в Float, и double to Double. Хотя, если нам нужно преобразовать строку в целое число , нам нужно использовать метод parseInt () , потому что String не является классом-оболочкой.

С другой стороны, для преобразования объекта-оболочки в примитивное значение мы можем использовать соответствующий метод, такой как intValue(), doubleValue () |/и т. Д:

int val = object.intValue();

Исчерпывающую справку можно найти здесь .

4. Автобокс и распаковка

В предыдущем разделе мы показали, как вручную преобразовать примитивное значение в объект.

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