Java зачем нужны классы обертки

Java зачем нужны классы обертки

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

В языке Java существует два типа переменных: примитивные, например int и boolean, а также ссылочные типы вроде Integer и Boolean (классы-обертки). Для каждого примитивного типа существует, соответствующий ему ссылочный тип.

Классы-обертки являются неизменяемыми: это означает, что после создания объекта его состояние (значение поля value) не может быть изменено; и задекларированы, как final (от этих классов невозможно наследоваться).

 Integer j = 1; // autoboxing int i = new Integer(1); // unboxing 

Процесс преобразования примитивных типов в ссылочные называется автоупаковкой (autoboxing), а обратный ему — автораспаковкой (unboxing).

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

В зависимости от реализации виртуальной машины, эти значения могут изменяться. Например, в виртуальной машине Oracle значения типа boolean сопоставляются со значениями 0 и 1 типа int (это связано с тем, что в VM нет инструкций для работы с булевыми значениями) и, как результат, занимают в памяти 32 бита.

Ссылочные переменные ссылаются на объекты, которые хранятся в куче, к ним мы имеем более медленный доступ (рекомендуем ознакомиться с понятиями Стек и Куча, для лучшего усвоения материала). Ссылочные типы имеют определенные накладные расходы относительно их примитивных аналогов.

Накладные расходы зависят от реализации конкретной JVM. Здесь мы приведем результаты для 64-х битной виртуальной машины со следующими параметрами:

Читайте также:  File manager php class

В результате, один экземпляр ссылочного типа на данной JVM занимает 128 бит. За исключением Long и Double, которые занимают 192 бита:

  • Boolean — 128 бит
  • Byte — 128 бит
  • Short, Character — 128 бит
  • Integer, Float — 128 бит
  • Long, Double — 192 бита

Обратите внимание, переменная типа Boolean занимает в 128 раз больше места чем соответствующий ей примитив, тогда как Integer занимает памяти как 4 int переменные.

который демонстрирует как массивы различных типов потребляют память (m) в зависимости от количества содержащихся элементов (e):

  • long, double: m = 128 + 64e
  • short, char: m = 128 + 64(e/4)
  • byte, boolean: m) = 128 + 64(e/8)
  • the rest: m = 128 + 64(e/2)

Это может показаться неожиданным, но массивы примитивных типов long и double занимают больше памяти чем их классы-обертки Long и Double соответственно.

Производительность Java кода, довольно тонкий вопрос, сильно зависящий от аппаратной части устройства на котором он исполняется, от различных оптимизационных процессов, выполняемых компилятором, от конкретной JVM, а также от других процессов, происходящих в операционной системе.

Мы уже упоминали ранее, что переменные примитивных типов живут в стеке, тогда как ссылочные переменные хранят ссылки на объекты расположенные в куче. Это важное свойство, определяющее скорость доступа к данным.

Чтобы продемонстрировать насколько операции над примитивными типами быстрее чем над их классами-обертками, создадим массив из миллиона элементов в котором все элементы одинаковы, кроме последнего. Затем мы попытаемся найти этот элемент и сравним результаты производительности работы массива переменных примитивных типов с массивом ссылочных переменных.

Мы используем известный инструмент тестирования производительности JMH, а результаты операции суммируем в диаграмме:

Как мы видим, даже выполнение такой простой операции требует значительно больше времени для классов-оберток, чем для их примитивных аналогов.

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

Источник

Классы оболочки

Очень часто необходимо создать класс, основное назначение которого содержать в себе какое-то примитивное значение. Например, как мы увидим в следующих занятиях, обобщенные классы и в частности коллекции работают только с объектами. Поэтому, чтобы каждый разработчик не изобретал велосипед, в Java SE уже добавлены такие классы, которые называются оболочки типов (или классы обертки, Wrappers).

К оболочкам типов относятся классы Double , Float , Long , Integer , Short , Byte , Character , Boolean , Void . Для каждого примитивного значения и ключевого слова void есть свой класс двойник. Имя класса, как вы видите, совпадает с именем примитивного значения. Исключения составляют класс Integer (примитивный тип int ) и класс Character (примитивный тип char ). Кроме содержания в себе значения, классы оболочки предоставляют обширный ряд методов, которые мы рассмотрим в этом уроке.

Объекты классов оболочек неизменяемые (immutable). Это значит, что объект не может быть изменен.

Все классы обертки числовых типов имеют переопределенный метод equals(Object) , сравнивающий примитивные значения объектов.

2. Конструкторы оболочек

В следующей таблицы для каждого класса оболочки указан соответствующий примитивный тип и варианты конструкторов. Как вы видите каждый класс имеет два конструктора: один на вход принимает значение соответствующего примитивного значения, а второй — значение типа String. Исключения: класс Character , у которого только один конструктор с аргументом char и класс Float , объявляющий три конструктора — для значения float , String и еще double .

Примитивный тип

Аргументы конструктора

Источник

Классы-оболочки в Java — руководство с примерами

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

Классы-оболочки Java являются Объектным представлением восьми примитивных типов в Java. Все классы-оболочки в Java являются неизменными и final. Начиная с Java 5 автоупаковка и распаковка позволяет легко конвертировать примитивные типы в их соответствующие классы-оболочки и наоборот.

В таблице ниже показаны примитивные типы и их классы-обертки в Java

Примитивный тип Класс-обертка Аргументы
byte Byte byte или String
short Short short или String
int Integer int или String
long Long long или String
float Float float, double или String
double Double double или String
char Character char
boolean Boolean boolean или String

Зачем нужны классы-оболочки в Java?

Разработчиками языка Java было принято очень умное решение отделить примитивные типы и классы-оболочки, указав при этом следующее:

  • Используйте классы-обертки, когда работаете с коллекциями.
  • Используйте примитивные типы для того, чтобы ваши программы были максимально просты.

Еще одним важным моментом является то, что примитивные типы не могут быть null, а классы-оболочки — могут.

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

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

Источник

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

У многих мог возникнуть вопрос: зачем задавать целочисленную переменную не int , а Integer ? Часто классы-обертки используют для того, чтобы сохранять данные в коллекции. Все дело в том, что коллекции — это набор объектов, и для того, чтобы оперировать примитивными типами как объектами, и были придуманы классы обертки.

Рассмотрим классы-обертки для примитивных типов данных.

Данные классы имеют название, которое происходит от названия примитивного типа данных, который они представляют: Double, Float, Long, Integer, Short, Byte, Character, Boolean .

Данные классы очень напоминают класс String . Объект обертку для примитивного типа можно создать как явно (используя конструктор), так и не явно (прямым присвоением примитива классу обертке) с помощью оператора = либо при передаче примитива в параметры метода (типа «класса-обертки»). Последнее еще называют автоупаковка (autoboxing).

public class AutoBoxing < public static void main(String[] args)< Integer a = new Integer(777); //явное создание переменной обертки int b = a; //неявное создание. > > 

Как и все объекты, переменные, созданные с помощью классов-оберток, будут храниться в куче ( heap ). Но, есть одно важное замечание, о котором часто любят спрашивать в тестах или на собеседованиях. Оно касается целочисленных классов оберток. Неявное создание таких переменных со значением в диапазоне -128 +127 будут храниться в пуле int-ов (В Java есть пул ( pool ) целых чисел в промежутке [-128;127]. Т.е. если мы создаем Integer в этом промежутке, то вместо того, чтобы каждый раз создавать новый объект, JVM берет их из пула). Потому такие обертки с одинаковыми значениями будут являться ссылками на один объект.

Автоупаковка переменных примитивных типов требует точного соответствия типа исходного примитива типу «класса-обертки». Попытка автоупаковать переменную типа byte в Short , без предварительного явного приведения byte->short вызовет ошибку компиляции.

public class AutoBoxing < public static void main(String[] args)< Integer integerA = new Integer(23); Integer integerB = new Integer(777); integerB = new Integer(888); System.out.println("integerA = " + integerA); Integer integerC = new Integer(666); Integer integerD = new Integer(2412); integerD = new Integer(1991); System.out.println("integerD = " + integerD); > > 

Результат работы программы:

integerA = 23 integerD = 1991 

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

Давайте посмотрим на самые популярные:

public class AutoBoxing < public static void main(String[] args)< String a = "45"; double b = Double.parseDouble(a); // наверное, самый популярный метод перевод из строки в целочисленный или дробный тип int c = Integer.parseInt(a); System.out.println(b); System.out.println(c); System.out.println(Integer.MAX_VALUE); // константа максимального значения System.out.println(Integer.bitCount(78)); // представляет число в двоичном виде System.out.println(Float.valueOf("80")); // возвращает целочисленный объект, содержащий значение указанного типа System.out.println(Integer.valueOf("444", 16)); // возвращает целочисленный объект, содержащий целое значение указанного строкового представления в 16-ричной системе счисления > > 

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

results matching » «

No results matching » «

Источник

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

Раньше Вы знакомились с примитивными типами данных (такими, как int, short, boolean и т.д.):

Variables Java_Vertex Academy

Тем не менее, Вы знаете, что Java — объектно-ориентированный язык программирования . Это значит, что в ней «все, что можно, представлено в виде объектов».

Поэтому, у примитивных типов есть объекты-аналоги — так называемые «классы оболочки» , или «wrapper» (с англ. «обертка, упаковка»):

wrap_1

Класс называется «оболочкой» потому, что он, по сути, копирует то, что уже существует, но добавляет новые возможности для работы с привычными типами .

О названиях

Имена классов нетрудно запомнить — они повторяют имена примитивных типов данных:

wrap_2

Обратите внимание — все классы оболочки пишутся с большой буквы:

wrap_3

Зачем так усложнять

Но зачем они нужны? Если есть обычный int, short, . , зачем нам Short и Integer ? Или, может, оставить только классы оболочки, и не пользоваться примитивами, раз у них функций больше ?

i-in3cvejg-evan-dennis

Примитивы и их аналоги, классы оболочки , существуют параллельно, потому что у каждого есть преимущества.

Например, обычный int занимает меньше места, и если нет необходимости проводить над ним особые операции, Ваш компьютер будет работать быстрее.

В свою очередь, с помощью класса-оболочки Integer можно выполнять специальные операции — например, перевести текст в число (с помощью метода .parseInt() для Integer-а ). Если попробовать сделать это с помощью кода самому придется изрядно повозиться.

Integer и int можно сравнить с компьютером и записной книжкой:

stocksnap_2ci87djpdzkopiya-stocksnap_0axtvi7jb2

Компьютер, безусловно, может больше, чем блокнот — но Вы не будете целый день носить с собой три килограмма для того, чтобы сделать несколько заметок?

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

Метод .parseInt()

Иногда в объекте типа String содержится число, и Вам нужно с ним работать дальше — умножать, делить, в степень возводить. Но нельзя! Строка же. Что делать?

Источник

Оцените статью