Для чего используются обертки примитивов в java

Pro Java

Страницы

4 мая 2015 г.

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

Мы уже сталкивались с классами обертками (wrapper classes) для примитивных типов, но пока не заостряли на них внимание. Сейчас же мы рассмотрим их более подробно, чтобы понять что такое методы классов и что такое поля классов.

Как вы уже знаете, в Java для хранения базовых типов данных, поддерживаемых языком, используются примитивные типы (также называемые простыми типами), такие как int или double. Примитивные типы, в отличие от объектов, используются для таких значений из соображений производительности. Применение объектов для этих значений добавляет нежелательные накладные расходы, даже в случае простейших вычислений.

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

Обертки для примитивных типов — это Double, Float, Long, Integer, Short, Byte, Character и Boolean. Эти классы предоставляют широкий диапазон методов, позволяющий в полной мере интегрировать примитивные типы в иерархию объектных типов Java.

И далее уже рассмотрим примеры работы с методами этих классов.

Для чего используются обертки примитивов в java. Смотреть фото Для чего используются обертки примитивов в java. Смотреть картинку Для чего используются обертки примитивов в java. Картинка про Для чего используются обертки примитивов в java. Фото Для чего используются обертки примитивов в java

По существу мы много раз использовали поле length массива args, для поучения количества его элементов. Это один из примеров работы с полями объекта класса.

Примером работы с методами класса являются строки 11 и 13.

В 11 строке мы проверяем если первый аргумент командной строки является строкой true, то тогда переменной wBoolean присваивается значение true. В ином случае оно остается равным false, как было задано при инициализации.

Пример вывода этой программы представлен ниже.

Для чего используются обертки примитивов в java. Смотреть фото Для чего используются обертки примитивов в java. Смотреть картинку Для чего используются обертки примитивов в java. Картинка про Для чего используются обертки примитивов в java. Фото Для чего используются обертки примитивов в java

Теперь небольшой пример использования класса Character:

Для чего используются обертки примитивов в java. Смотреть фото Для чего используются обертки примитивов в java. Смотреть картинку Для чего используются обертки примитивов в java. Картинка про Для чего используются обертки примитивов в java. Фото Для чего используются обертки примитивов в java

В данном примере использован статический метод isDigit класса Character, для определения является ли элемент массива символом или числом.

Метод isDigit возвращает true, если переданный ему как параметр тип char является числом, во всех других случаях возвращается false.

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

Класс Charaster содержит множество полезных методов и полей. Все это можно узнать из оригинальной документации.

Вывод данной программы может быть таким (зависит от аргументов командной строки):

Для чего используются обертки примитивов в java. Смотреть фото Для чего используются обертки примитивов в java. Смотреть картинку Для чего используются обертки примитивов в java. Картинка про Для чего используются обертки примитивов в java. Фото Для чего используются обертки примитивов в java

Ну и несколько примеров с классами обертками для числовых типов:

Для чего используются обертки примитивов в java. Смотреть фото Для чего используются обертки примитивов в java. Смотреть картинку Для чего используются обертки примитивов в java. Картинка про Для чего используются обертки примитивов в java. Фото Для чего используются обертки примитивов в java

Тут просто показано использование некоторых статических методов классов Byte и Integer, а так же использование статических полей типа MAX_VALUE.

Статический метод parseInt преобразует строку в число типа int.

Статический метод bitCount подсчитывает количество битов равных единице в переданном, как аргумент числовом типе.

Кроме этих методов и полей, у классов-оберток есть еще множество других. Поэтому, если вам понадобятся какие-либо операции над этими типами, то посмотрите сперва в стандартной библиотеке.

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

Для чего используются обертки примитивов в java. Смотреть фото Для чего используются обертки примитивов в java. Смотреть картинку Для чего используются обертки примитивов в java. Картинка про Для чего используются обертки примитивов в java. Фото Для чего используются обертки примитивов в java

На этом я думаю с этой темой закончим. Цель была познакомиться с тем, что такое методы и поля классов. Хотя пока, может, это все ясности и не добавило, но на подкорку должно было осесть.

Далее будем рассматривать массивы и строки. Все они относятся к ссылочным типам данных Java и соответственно имеют свои поля и методы. То есть мы будем еще глубже знакомиться с тем что такое объекты и с чем их едят. И затем уже перейдем непосредственно к понятию класса.

Источник

Типы-обертки в Java

1. Список типов-оберток

Все вы знаете, что в Java есть 8 примитивных типов, которые не являются классами. С одной стороны, это хорошо: они простые и занимают мало места, а с другой — иногда нужны именно классы. Зачем именно они, вы узнаете в следующей лекции.

Вот список таких типов, ничего не узнаете?

Примитивный типКласс-обертка

Все объекты классов-оберток являются неизменяемыми ( immutable ).

Упрощенный код класса Integer выглядит примерно так:

Метод возвращает значение

Статический метод создает новый объект Integer для переменной типа int

2. Преобразование типа int к Integer

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

Разберем взаимодействие примитивных типов и их типов-оберток на примере типа int. Вот как бы выглядел код преобразования типа int к типу Integer и наоборот:

3. Autoboxing и unboxing

Однако даже простые операции с типом Integer писать непросто.

КодОписание
Оборачиваем 5 в класс Integer
Получаем значение из объекта Integer
Создаем новое значение Integer == 10

Код довольно громоздкий, не находите?

Ваш кодЧто видит компилятор
КодЧто сгенерирует компилятор

4. Сравнение переменных классов-оберток

КодВывод на экран

Переменные a и b хранят не значения (как типы int ), а ссылки на объекты. Поэтому важно помнить, как правильно их сравнивать:

Источник

Познаём Java. Третья чашка: примитивные типы, и объекты. Базовые конструкции

Типа реальные типы

Думаю, после краткого экскурса в возможности Java и прочитывания пары десятков строк кода примеров, вам захотелось узнать, чем должен уметь оперировать каждый Java-программист. Что ж, давайте поговорим о примитивных типах, классах (в том числе нескольких основных), сравнении, передаче параметров и простых структурах в Java.

Базовые типы

вы получите именно 200, а не что-то ещё — переменные будут автоматически приведены к нужному типу.
Есть несколько способов задавать значение целочисленным переменным, например:

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

Операции с базовыми типами

Сравнение

Почему нельзя писать == для объектов

Это чудо вернёт вам 3 раза false. Потому что мы явно указали создание новых объектов с одним значением, и сравнение по ссылке вернуло false.
А в первых двух случаях произошло развёртывание, так как операция сравнения определена только для примитивных типов.
Мораль: == только для примитивных типов.

«Кстати, строки»

Здесь, как вы видите приведены 2 способа инициализации, второй при этом хоть и избыточен, но гарантирует что ваша строка будет «новой».
Строго говоря, любая конструкция в Java в двойных кавычках — уже новая строка, созданная и закешированная (см. ниже).

Кроме того, для строк есть операция соединения (конкатенации):
String r = «Привет » + «мир»;

Конструкторы, ссылки и значения: куда что идёт, и куда оно уходит.

Когда вы создаёте новый объект, вы начинаете его жизненный цикл.
Начинается он с вызванного вами конструктора. Да? Нет.

При первом упоминании класса вызываются по порядку все его статик-блоки вида static <. >лежащие в классе.
Статик-блоки родителей вызываются по мере их упоминания.
Затем вызываются по порядку все блоки вида <. >верхнего родителя.
Далее — вызывается конструктор этого же родителя.
Затем последние 2 шага повторяются для каждого класса иерархии.
В последнюю очередь вызываются <>-блоки и конструктор вашего класса.

Далее — ваш объект живёт до тех пор, пока на него есть ссылки.
Как только ссылки на объект теряются — он подхватывается сборщиком мусора и уничтожается. Никаких a = null чтобы «стереть ссылку» писать не нужно — java и так знает, когда вы перестали использовать объект.
Перед уничтожением вызывается метод finalize вашего милого объекта.

Кстати, иногда встречается такая ошибка: человеку в метод передают некий объект, а он присваивает ему null, думая, что таким образом он объект сотрёт из всех ссылок. Нет, этого не будет, будет уничтожена только это ссылка. Однако, если ссылка была всего одна — разумеется, в этом случае объекту придёт конец.

Как выбираются конструкторы.

В предыдущем параграфе были упомянуты конструкторы. Их у класса может быть много, у каждого — свои параметры.
По умолчанию, если вы ручками не написали ни одного, то будет создан пустой конструктор без парамертов.
Каждый из них обязан вызывать конструктор класса-родителя.
Чтобы это сделать, вы должны дописать первой строкой в конструктор super-вызов:

public HelloWorld() <
super();
>

super-конструктор — это конструктор родителя. Вы можете использовать любой, из тех что у него есть.
На самом деле, если вы его не напишете — за вас это сделает компилятор. А что будет если у класса-родителя нет конструктора без параметров?
В этом случае вы должны явно вызывать super-конструктор всегда, и передавать ему параметры как для конструктора класса-родителя.

Что у вас там про кеширование?

Я упоминал кеширование объектов. Немного поясню. Дело в том, что упоминание чисел/строк — рутина, которая сваливается на нас постоянно. Чтобы не хранить в памяти тысячу интеджеров с 1 в качестве значения был сделан механизм кеширования. Он гарантирует вам, что на каждую вашу еденичку или строку будет создан ровно один объект в памяти, а при автоматическом развёртывании он и будет использован. Шутка в том, что разработчики платформы ограничили количество кешируемых чисел пределами, упомянутыми выше.

«Кстати, строки», часть 2 — будьте аккуратны.

Надеюсь, смог дать понять, как работать с простыми объектами. На этом мог бы и закончить про них, но вспомнил про массивы.

Массивы

Из приятных бонусов, массивы имеют поле length, то есть длину массива вы знаете всегда и она фиксирована.

Базовые конструкции Java

if(любое boolean-выражение или переменная)<>else<>
for(действия до начала цикла; условие продолжения цикла; действие после каждого шага)<>
while(условие продолжения цикла)<>
do<>while(условие продолжения цикла)
switch(переменная числового или enum)
for(Тип имяПеременной: массив)<>

На последнем хотел бы остановиться подробнее. В Java так выглядит цикл for-each. Он перебирает каждый элемент массива, например так:

Кроме того, for-each применим для любой коллекции, и не только для них. Об этом расскажу потом.

Источник

Для чего используются обертки примитивов в java

Объектные обёртки. Autoboxing

Так как иногда таки возникает необходимость создать список, например, целых чисел, можно создать класс, который позволит представить целое число как объект.

Autoboxing

Компилятор может вставить вызовы valueOf и *Value автоматически, это называется autoboxing и autounboxing соответственно.

Кэш объектов

С этой особенностью связан известный паззлер, т. е. код, поведение которого сбивает с толку:

Пример использования

Используйте обёртки только при необходимости

Обёртки (boxed primitives) занимают в памяти больше места, чем примитивы. Так как объектные обёртки иммутабельны, любая арифметическая операция выделяет новый объект с новым значением. Например, в этом коде вычисления проводятся с примитивами, как и должно быть:

Но если в первой строке (без причины) использовать объектную обёртку,

то этот код отработает в несколько раз медленнее и выделит много новых объектов, создавая лишнюю работу для сборщика мусора.

Познаём Java. Третья чашка: примитивные типы, и объекты. Базовые конструкции

Думаю, после краткого экскурса в возможности Java и прочитывания пары десятков строк кода примеров, вам захотелось узнать, чем должен уметь оперировать каждый Java-программист. Что ж, давайте поговорим о примитивных типах, классах (в том числе нескольких основных), сравнении, передаче параметров и простых структурах в Java.

Базовые типы

вы получите именно 200, а не что-то ещё — переменные будут автоматически приведены к нужному типу.
Есть несколько способов задавать значение целочисленным переменным, например:

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

Операции с базовыми типами
Классы

Кроме того, есть ещё метод finalize, который стоит переопределить, если перед смертью ваш объект должен «написать завещание» и набор методов для работы с потоками, которые могут усыпить/разбудить текущий поток.

Как с этим обращаться?
Сравнение
Почему нельзя писать == для объектов

Далее — ваш объект живёт до тех пор, пока на него есть ссылки.
Как только ссылки на объект теряются — он подхватывается сборщиком мусора и уничтожается. Никаких a = null чтобы «стереть ссылку» писать не нужно — java и так знает, когда вы перестали использовать объект.
Перед уничтожением вызывается метод finalize вашего милого объекта.

Кстати, иногда встречается такая ошибка: человеку в метод передают некий объект, а он присваивает ему null, думая, что таким образом он объект сотрёт из всех ссылок. Нет, этого не будет, будет уничтожена только это ссылка. Однако, если ссылка была всего одна — разумеется, в этом случае объекту придёт конец.

Как выбираются конструкторы.

В предыдущем параграфе были упомянуты конструкторы. Их у класса может быть много, у каждого — свои параметры.
По умолчанию, если вы ручками не написали ни одного, то будет создан пустой конструктор без парамертов.
Каждый из них обязан вызывать конструктор класса-родителя.
Чтобы это сделать, вы должны дописать первой строкой в конструктор super-вызов:

super-конструктор — это конструктор родителя. Вы можете использовать любой, из тех что у него есть.
На самом деле, если вы его не напишете — за вас это сделает компилятор. А что будет если у класса-родителя нет конструктора без параметров?
В этом случае вы должны явно вызывать super-конструктор всегда, и передавать ему параметры как для конструктора класса-родителя.

Что у вас там про кеширование?

Я упоминал кеширование объектов. Немного поясню. Дело в том, что упоминание чисел/строк — рутина, которая сваливается на нас постоянно. Чтобы не хранить в памяти тысячу интеджеров с 1 в качестве значения был сделан механизм кеширования. Он гарантирует вам, что на каждую вашу еденичку или строку будет создан ровно один объект в памяти, а при автоматическом развёртывании он и будет использован. Шутка в том, что разработчики платформы ограничили количество кешируемых чисел пределами, упомянутыми выше.

«Кстати, строки», часть 2 — будьте аккуратны.

Надеюсь, смог дать понять, как работать с простыми объектами. На этом мог бы и закончить про них, но вспомнил про массивы.

Массивы

char [] asd = new char [5]; //пустой массив на 5 символов
char [] ghj = new char [] ;//массив на 2 символа

Из приятных бонусов, массивы имеют поле length, то есть длину массива вы знаете всегда и она фиксирована.

Базовые конструкции Java

if(любое boolean-выражение или переменная)<>else<>
for(действия до начала цикла; условие продолжения цикла; действие после каждого шага)<>
while(условие продолжения цикла)<>
do<>while(условие продолжения цикла)
switch(переменная числового или enum)
for(Тип имяПеременной: массив)<>

На последнем хотел бы остановиться подробнее. В Java так выглядит цикл for-each. Он перебирает каждый элемент массива, например так:

char [] chars = new char [] ;
for ( char a : chars)

Кроме того, for-each применим для любой коллекции, и не только для них. Об этом расскажу потом.

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

На очень высоком уровне я знаю, что нам нужно «обернуть» примитивные типы данных, такие как int и char, используя их соответствующие классы-оболочки для их использования в коллекциях Java. Я хотел бы понять, как Коллекции Java работают на низком уровне, спрашивая: «Почему нам нужно обернуть примитивные типы данных в качестве объектов, чтобы использовать их в коллекциях?» Я заранее благодарю вас за вашу помощь.

11 ответов

На уровне виртуальной машины это потому, что примитивные типы представлены по-разному в памяти по сравнению со ссылочными типами, такими как java.lang.Object и его производные типы. Примитивный int в Java, например, составляет всего 4 байта в памяти, тогда как Object занимает как минимум 8 байтов сам по себе, плюс еще 4 байта для его ссылки. Такой дизайн является простым отражением того факта, что процессоры могут более эффективно обрабатывать примитивные типы.

Итак, один ответ на ваш вопрос «зачем нужны типы обертки» — это из-за улучшения производительности, которое он позволяет.

Но для программистов такое различие добавляет некоторые нежелательные когнитивные накладные расходы (например, не может использовать int и float в коллекциях.) На самом деле, вполне возможно сделать дизайн языка, скрывая это различие — многие языки сценариев делают это, и CLR делает это. Начиная с 1.5, Java тоже делает это. Это достигается за счет того, что компилятор молча вводит необходимое преобразование между примитивным представлением и представлением Object (которое обычно называют бокс/распаковкой.)

Итак, еще один ответ на ваш вопрос: «Нет, нам это не нужно», потому что компилятор делает это автоматически для вас, и в определенной степени вы можете забыть, что происходит за сценой.

Поскольку коллекции Java могут хранить только ссылки на объекты (поэтому вам нужно приставить примитивы для их хранения в коллекциях).

Прочтите эту короткую статью на Autoboxing для получения дополнительной информации.

Если вам нужны подробные подробные сведения, это в значительной степени сводится к следующему:

Локальные примитивы хранятся в стеке. Коллекции хранят свои значения через ссылку на ячейку памяти объекта в куче. Чтобы получить эту ссылку для локального примитива, вам нужно вставить (принять значение в стеке и обернуть его для хранения в куче) значение.

Чтобы сохранить значения примитивного типа в классах коллекции, нам требуется Wrapper classe.

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

В коллекции используются Generics. Framework Collection предназначен для сбора, хранения и обработки данных любого класса. Поэтому он использует общий тип. Используя Generics, он может хранить данные ЛЮБОГО КЛАССА, имя которого указано в его объявлении.

Теперь у нас есть различные сценарии, в которых нужно хранить примитивные данные таким же образом, в которых работает коллекция. У нас нет возможности хранить примитивные данные, используя классы Collection, такие как ArrayList, HashSet и т.д., Потому что классы Collection могут хранить только объекты. Таким образом, для хранения примитивных типов в коллекции мы предоставляем классы-оболочки.

Ну, причина в том, что коллекции Java не различают примитив и объект. Он обрабатывает их все как Object, и поэтому ему понадобится обертка. Вы можете легко создать собственный класс коллекции, который не нуждается в оболочке, но в конце вам придется создавать по одному для каждого типа char, int, float, double и т.д., Умножать типы коллекций (Set, Карта, Список, + их реализация).

Можете ли вы представить себе, как это скучно?

И дело в том, что производительность, которую он приносит, без использования обертки, практически не имеет значения для большинства приложений. Однако, если вам нужна очень высокая производительность, некоторые библиотеки для примитивных коллекций также доступны (например, http://www.joda.org/joda-primitives/)

Это для С#, но та же концепция применима к Java. И Джон Скит написал ответ.

Прочитайте все ответы, но ни один из них не объясняет это просто в непрофессиональных условиях.

Класс оболочки обертывает (охватывает) вокруг типа данных (может быть любым примитивным типом данных, таким как int, char, byte, long) и делает его объектом.

Вот несколько причин, по которым необходимы классы-оболочки:

Классы Wrapper могут быть созданы двумя способами:

Использование valueOf() статических операторов:

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

Как и класс String, Wrappers предоставляют дополнительную функциональность и позволяют программисту сделать немного больше с процессом хранения данных. Таким образом, люди используют класс String, например.

String uglyString = «fUbAr»; String myStr = uglyString.toLower();

так и они могут с помощью Wrapper. Подобная идея.

Это в дополнение к проблеме ввода коллекций/дженериков, упомянутых выше Bharat.

Источник

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

Для чего используются обертки примитивов в java. Смотреть фото Для чего используются обертки примитивов в java. Смотреть картинку Для чего используются обертки примитивов в java. Картинка про Для чего используются обертки примитивов в java. Фото Для чего используются обертки примитивов в java

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

Стоить уточнить, что в данной статье будут рассмотрены только классы обертки для примитивных типов данных.

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

Для чего используются обертки примитивов в java. Смотреть фото Для чего используются обертки примитивов в java. Смотреть картинку Для чего используются обертки примитивов в java. Картинка про Для чего используются обертки примитивов в java. Фото Для чего используются обертки примитивов в java

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

public class AutoBoxingExample <

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

int b = a ; //неявное создание.
>
>

Для чего используются обертки примитивов в java. Смотреть фото Для чего используются обертки примитивов в java. Смотреть картинку Для чего используются обертки примитивов в java. Картинка про Для чего используются обертки примитивов в java. Фото Для чего используются обертки примитивов в java

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

public class AutoBoxingExample <

public static void main ( String [ ] args ) <
Integer a = new Integer ( 5 ) ;
Integer b = new Integer ( 5 ) ;
b = new Integer ( 3 ) ;

Integer c = new Integer ( 444 ) ;
Integer d = new Integer ( 444 ) ;
d = new Integer ( 456 ) ;

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

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

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

public class AutoBoxingExample <

Хотелось бы еще рассмотреть создание Boolean переменной. Этот вопрос встречается достаточно часто в тестах:

public class BooleanExample <

public static void main ( String [ ] args ) <
Boolean b1 = new Boolean ( false ) ; //false
Boolean b2 = new Boolean ( «false» ) ; //false
Boolean b3 = new Boolean ( true ) ; //true
Boolean b4 = new Boolean ( «true» ) ; //true
Boolean b5 = new Boolean ( «hi there» ) ; //false

На самом деле методов очень много, но это самые популярные и самые используемые для меня.

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *