Классы оболочки
Очень часто необходимо создать класс, основное назначение которого содержать в себе какое-то примитивное значение. Например, как мы увидим в следующих занятиях, обобщенные классы и в частности коллекции работают только с объектами. Поэтому, чтобы каждый разработчик не изобретал велосипед, в 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 у каждого примитивного типа есть соответствующий «объектный» тип. Например, для int существует пара в виде Integer . Последний представлен классом и называется классом-оберткой.
// Примитивный тип // Можно так var value = 42; // int // Или так int value = 42; // int // Ссылочный тип // Можно так Integer value = 42; // Integer Integer value = new Integer(42); // Integer var value = new Integer(42); // Integer // Так написать нельзя, // потому что невозможно вывести тип value // null может быть присвоено любому ссылочному типу // var value = null;
То же самое и для всех остальных примитивных типов:
| Примитивный тип | Класс-обертка |
|---|---|
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| char | Character |
| boolean | Boolean |
Классы-обертки нужны для нескольких целей, которых по разным причинам невозможно решить с помощью примитивных типов.
Совместимость и единообразие
Многие возможности Java завязаны на то, что типы представлены классами, только в этом случае они смогут быть использованы как параметры методов или их возвращаемое значение. К ним, например, относятся обобщенные типы и как их следствие коллекции. Все это мы рассмотрим в следующих курсах.
// Так написать нельзя // var items = new ArrayList; var items = new ArrayListInteger>;
null
Примитивные типы всегда содержат какое-то осмысленное значение. На практике же, значение может быть не определено. Особенно часто такое происходит, когда данные поступают из внешних источников. Для представления таких данных нужно специальное обозначение и возможность использовать это значение. В Java, как и в большинстве других языков, таким значением является null . Его можно использовать только с классами-обертками.
// Ошибка! int value = null; // Работает Integer value = null;
По этой причине, множество методов ожидает на вход классы-обертки, а не примитивные типы.
Утилиты и значения
Классы-обертки содержат в себе полезные значения и методы, для своих типов. Например, в Integer есть данные о максимальном и минимальном значениях для типа, там же можно найти методы, которые преобразуют другие типы в числа.
var max = Integer.MAX_VALUE; var min = Integer.MIN_VALUE; // Преобразование в число // Возвращает Integer var value = Integer.valueOf("42"); // 42 // Возвращает int var value = Integer.parseInt("42"); // 42
Почему так устроено?
Зачем тогда нужны примитивные типы если есть классы-обертки? Ответ кроется в производительности. Работа с примитивными типами как объектами значительно ухудшает производительность программы. Поэтому по умолчанию создаются объекты именно примитивных типов.
// Тип: boolean var hasErrors = true;
Боксинг и анбоксинг (Boxing and Unboxing)
По логике, такая система должна приводить к постоянному конвертированию типов в коде, так как где-то создаются примитивные типы, где-то нужны классы-обертки и наоборот. К счастью, этого почти никогда не происходит благодаря механизму автобоксинга (Autoboxing). Тип преобразуется автоматически в тот момент, когда это нужно.
int value = 42; // int -> Integer Integer wrappedInt = value; // Autoboxing // Integer -> int unboxedInt = wrappedInt; // Auto-unboxing
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Классы Integer, Character, Boolean
Часто бывает предпочтительней работать с объектами, а не с примитивными типами. Так, например, при использовании коллекций, просто необходимо значения примитивных типов каким-то образом представлять в виде объектов. Для этих целей и предназначены так называемые классы-обертки (wrapper classes). Для каждого примитивного типа Java существует свой класс-обертки. Такой класс является неизменяемым, то есть, для изменения значения необходимо создавать новый объект. К тому же класс-обертка имеет атрибут final и его нельзя наследовать.
Все классы-обертки (кроме Void) реализуют интерфейс java.io.Serializable, поэтому объекты любого класса-обертки (кроме Void) могут быть сериализованы. Это имеет важное значение для «сетевых» пересылок объектов.
Классы-обертки содержат статическое поле TYPE — содержащее объект Class, соответствующий примитивному оборачиваемому типу. Также классы-обертки содержат статические методы для обеспечения удобного манипулирования соответствующими примитивными типами, например, преобразование к строковому виду.
| Примитивный тип | Класс-обертка |
|---|---|
| byte | Byte |
| short | Short |
| char | Character |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| boolean | Boolean |
Wrapper classes числовых типов (Byte, Short, Integer, Long, Float, Double) наследуются от класса Number, который содержит код, общий для всех классов-оберток числовых типов. Все классы-обертки реализуют интерфейс Comparable.
Классы-обертки числовых типов имеют метод equals(Object), сравнивающий примитивные значения объектов. Но с этим надо быть предельно внимательным. Так в результате выполнения следующего кода
public static void main(String[] args)
мы увидим в консоли следующий текст :
i = 1, b = 1 i.equals(b) = false, b.equals(i) = false
Данный результат связан с тем, что во всех классах-обертках метод equals() сначала производит проверку на совпадение типов (классов), и если нет совпадения, то сразу же возвращает false. В JDK 1.3.1 для класса-обертки Integer метод equals() определен следующим образом :
public boolean equals(java.lang.Object obj)
Класс Number
Абстрактный класс Number является суперклассом для классов Byte, Double, Float, Integer, Long и Short. Наследники Number должны обеспечить методы преобразовывания числовых значений в byte, double, float, int, long и short.
Класс Number имеет один конструктор :
public Number()
Методы класса Number :
| Метод | Описание |
|---|---|
| byte byteValue() | преобразование значения в тип byte |
| abstract double doubleValue() | преобразование значения в тип double |
| abstract float floatValue() | преобразование значения в тип float |
| abstract int intValue() | преобразование значения в тип int |
| abstract long longValue() | преобразование значения в тип long |
| short shortValue() | преобразование значения в тип short |
Класс Integer
Конструкторы класса Integer
- Integer(int value) — создание объекта Integer на основе аргумента int
- Integer(String s) — создание объекта Integer на основе строкового аргумента
Поля класса Integer
- static int MAX_VALUE — максимальная величина типа int
- static int MIN_VALUE — минимальная величина типа int
- static Class TYPE — объект класса, представляющий простой тип int
Наиболее значимые методы класса Integer
| Метод | Описание |
|---|---|
| byte byteValue() | преобразование значения в тип byte |
| int compareTo(Integer integer) | сравнение двух целых чисел |
| int compareTo(Object o) | сравнение значения с другим объектом |
| Integer decode(String nm) | перевод строки в Integer |
| double doubleValue() | преобразование значения в тип double |
| boolean equals(Object obj) | сравнение с другим объектом |
| float floatValue() | преобразование значения в тип float |
| int hashCode() | получение hashcode для обьекта |
| int intValue() | преобразование значения в тип int |
| long longValue() | преобразование значения в тип long |
| int parseInt(String s) | преобразование текстового значения в тип int |
| int parseInt(String s, int radix) | преобразование текстового значения со знаком в системе счисления, определенной во втором аргументе, в тип int |
| short shortValue() | преобразование значения в тип short |
| String toBinaryString(int i) | преобразование целочисленного значения i в текстовый вид с базой 2 (двоичный) |
| String toHexString(int i) | преобразование целочисленного значения i в текстовый вид с базой 16(шестнадцатиричный) |
| String toOctalString(int i) | преобразование целочисленного значения i в текстовый вид с базой 8(восьмиричный) |
| String toString() | преобразование значения в тип String |
| String toString(int i) | преобразование значения i в тип String |
| String toString(int i, int radix) | преобразование целочисленного значения i в строку в заданной системе счисления radix |
| Integer valueOf(String s) | создание объекта Integer, инициализированного величиной, определенной в строковой переменной s |
| Integer valueOf(String s, int radix) | создание объекта Integer, инициализированного величиной, определенной в строковой переменной s, записанной в системе счисления radix |
Методы parseInt(), преобразующие текстовое значение в целочисленное, не следует путать с методами valueOf(), возвращающие класс-обертку. Если переданная на вход строка содержит нецифровые символы, то методы возбуждают исключение NumberFormatException.
Дополнительную информацию о классе Integer можно получить на странице Кэширование класса Integer
Класс Byte
Класс Byte является стандартной оболочкой для байтовых величин.
Конструкторы класса Byte
- Byte (byte value) — создание объекта Byte с определенным значением value;
- Byte (String s) — создание объекта Byte на основе текстового значения s.
Поля класса Byte
- static int MAX_VALUE — максимальная величина типа byte
- static int MIN_VALUE — минимальная величина типа byte
- static Class TYPE — объект класса, представляющий простой байтовый тип byte
Методы класса Byte
| Метод | Описание |
|---|---|
| byte byteValue() | получение значения типа byte |
| int compareTo(Byte byte) | сравнение с объектом Byte |
| int compareTo(Object o) | сравнение с другим объектом |
| static Byte decode(String nm) | преобразование строки в Byte |
| double doubleValue() | преобразование значения в double |
| boolean equals(Object obj) | проверка на равенство с другим объектом |
| float floatValue() | преобразование значения в float |
| int hashCode() | получение hash-кода объекта |
| int intValue() | преобразование значения в int |
| long longValue() | преобразование значения в long |
| static byte parseByte(String s) | преобразование текстового значения в byte |
| static byte parseByte(String s, int radix) | преобразование текстового значения в системе счисления radix в байт |
| short shortValue() | преобразование значения в short |
| String toString() | преобразование значения в String |
| static String toString(byte b) | преобразование байтового значения в String |
| static Byte valueOf(String s) | преобразование текстового значения в Byte |
| static Byte valueOf(String s, int radix) | преобразование текстового значения в системе счисления radix в Byte |
Класс Boolean
Класс Boolean является оболочкой простого логического объекта. Объект типа Boolean содержит единственное поле логического типа. Кроме того, этот класс включает методы преобразования boolean в String и обратно, а также константы и методы полезные при работе с логическим типом.
Конструкторы класса Boolean
- Boolean (boolean value) — создание логического объекта на основе аргумента;
- Boolean (String s) — создание логического объекта на основе текстового значения s [«true» | «false»].
Поля класса Boolean
- static Boolean FALSE — логический объект, соответствующий значению «ложь»
- static Boolean TRUE — логический объект, соответствующий значению «истина»
- static Class TYPE — объект класса, представляющий простой логический тип
Методы класса Boolean
| Метод | Описание |
|---|---|
| boolean booleanValue() | получение логического значения |
| boolean equals(Object obj) | функция возвращает логическое значение по результату сравнения переданного объекта с текущим |
| static boolean getBoolean(String name) | преобразование текстового значения в логическое |
| int hashCode() | получение hash-кода объекта |
| String toString() | преобразование в текстовое значение |
| static Boolean valueOf(String s) | преобразование текстового значения в Boolean |
Класс Void
Класс-обертка Void, в отличии от остальных, НЕ реализует интерфейс java.io.Serializable и не имеет открытого конструктора. Более того, экземпляр класса Void вообще не может быть получен. Он нужен только для получения ссылки на объект, соответствующий void. Эта ссылка представлена статической константой TYPE. Выражение void.class == Void.TYPE вернет «true».
В большинстве случаев, если нужно проверить возвращаемый тип метода (например, через рефлексию) можно использовать void.class — не перепутаешь с Void.class.
Использовать Void можно, например, в случаях, когда имеется обобщенный класс (generic) и необходимо, чтобы метод ничего не возвращал :
interface IVoid < T doStuff(); >class A implements IVoid < @Override public Void doStuff() < // . return null; // ничего другого вернуть нельзя (если // не хитрить с рефлексией, конечно) >>
Класс Character
Для хранения символов Java использует специальный тип char. В отличие от языка C/C++, где char представляет собой целочисленный тип с размером 8 бит, в Java для char применяется кодировка Unicode и для хранения Unicode-символов используется 16 бит. Диапазон допустимых значений — от 0 до 65536 (отрицательных значений не существует).
Класс Character является оболочкой вокруг типа char. Чтобы получить значение типа char, содержащее в объекте Character, необходимо вызвать метод charValue().
Конструктор класса Character
Character имеет только один конструктор, которому в качестве параметра передается значение char.
Character ch = new Character('a');
Помимо констант MIN_VALUE и MAX_VALUE, Character содержит две константы MIN_RADIX и MAX_RADIX, которые равны минимальному и максимальному основанию системы счисления, которые используются методами (представленными ниже) для перевода отдельного цифрового символа в его целочисленный эквивалент и наоборот. Основание должно находиться в диапазоне 2–36; цифры свыше 9 представлены буквами от A до Z или их эквивалентами в нижнем регистре.
Методы класса Character
| Метод | Описание |
|---|---|
| public char charValue() | метод возвращает значение char |
| public static int digit(char chr, int radix) | метод возвращает численный эквивалент цифры chr в системе счисления с основанием radix. Если символ chr не является допустимой цифрой, то возвращается –1 |
| public static char forDigit(int digit, int radix) | метод возвращает символьное значение заданной цифры в заданной системе счисления. Если цифра является недопустимой в этой системе, возвращается символ \u0000 |
| public static boolean isDefined(char chr) | метод возвращает true, если символ chr определен в стандарте Unicode |
| public static boolean isDigit(char chr) | метод проверяет, является ли chr цифрой |
| public static boolean isDigitOrLetter(char chr) | метод проверяет, является ли chr цифрой или буквой |
| public static boolean isIdentifierStart(char chr) | метод проверяет, является ли chr подходящим для того, чтобы с него начиналось наименование переменной |
| public static boolean isLetter(char chr) | метод проверяет, является ли chr буквой |
| public static boolean isLowerCase(char chr) | метод возвращает true, если символ chr является буквой нижнего регистра |
| public static boolean isUpperCase(char chr) | метод возвращает true, если символ chr является буквой верхнего регистра |
| public static boolean isSpace(char chr) | медод возвращает true, если chr является стандартным символом-разделителем — ‘ ‘, ‘\t’, ‘\n’, ‘\f’ или ‘\r’ |
| public static char toLowerCase(char chr) | метод переводит символ chr в нижний регистр. Если эквивалент символа в нижнем регистре отсутствует, возвращается chr |
| public static char toUpperCase(char chr) | метод переводит символ chr в верхний регистр. Если эквивалент символа в верхнем регистре отсутствует, возвращается chr |
| public static char toTitleCase(char chr) | метод переводит символ ch в заглавный регистр. Если эквивалент символа в заглавном регистре отсутствует, возвращается chr |
| public String toString() | метод переводит символ, содержащийся в классе, в строку с тем же символом |
Классы оболочки в Java
Раньше Вы знакомились с примитивными типами данных (такими, как int, short, boolean и т.д.):

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

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

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

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

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


Компьютер, безусловно, может больше, чем блокнот — но Вы не будете целый день носить с собой три килограмма для того, чтобы сделать несколько заметок?
Кроме того, есть ситуации, когда нельзя использовать объекты, или наоборот, когда можно использовать только объекты.
Метод .parseInt()
Иногда в объекте типа String содержится число, и Вам нужно с ним работать дальше — умножать, делить, в степень возводить. Но нельзя! Строка же. Что делать?