Что это вообще такое упаковка и распаковка (boxing/unboxing) и зачем?
Был бы рад примерам.
Работа с объектами неизбежно влечет за собой накладные расходы по памяти и быстродействию. Чтобы избежать этого, используются переменные примитивных типов. Это, по сути, простые переменные, как в C или С++. byte занимает 1 байт памяти, int и float - по 4 байта, long и double - по 8 байт и т. д. В отличие от операций с объектами, операции с переменными примитивных типов не требуют выделения/освобождения памяти и выполняются быстро - они в в большинстве случаев в конечном счете компилируются в простые процессорные инструкции, что позволяет программам на Java часто работать со скоростью, сравнимой с программами, написанными на простых компилируемых (непосредственно в машинный код) языках (типа тех же C, С++).
Неудобство с ними в том, что с ними нельзя делать то, что можно делать со всеми объектами - они не имеют методов (нельзя, например написать
их нельзя помещать в коллекции и прочее.
int a = 5;
ArrayList list = new ArrayList();
String s = a.toString(); // Ошибка
list.add(a)) // Можно, но произойдет автоупаковка
// и в коллекцию будет помещен Integer
Для того, чтобы обойти это неудобство, для всех примитивных типов существуют соответствующие классы-оболочки, объекты которых могут хранить значения примитивных типов, но обладает всеми свойствами нормальных объектов:
Integer a = 5;
ArrayList list = new ArrayList();
String s = a.toString(); // OK
list.add(a)) // OK
Создание объекта-оболочки из переменной примитивного типа называется упаковкой (boxing), а получение значения примитивного типа из объекта-оболочки -- распаковкой. Объектам-оболочкам можно присваивать значения примитивных типов, а переменным примитивных типов - значения переменных-оболочек, при этом при необходимости автоматически создаются объекты-оболочки с соответствующими значениями (автоупаковка) или наоборот, примитивные значения извлекаются из оболочек (автораспаковка):
В тех случаях, когда по контексту требуются объекты (присваивание, вызов метода с передачей параметров), а мы используем значения примитивных типов (переменные или выражения типа 2 * 3), всегда происходит автоупаковка.
int a = 5;
Integer b = 10;
a = b; // OK, атораспаковка
b = a * 123; // OK, автоупаковка
Все объекты-оболочки -- неизменяемые (immutable) типы, т. е. когда мы присваиваем им новое значение, фактически на замену прежнему объекту создается новый.
В версиях ниже JDK 1.5 было не легко преобразовывать примитивные типы данных, такие как int, char, float, double в их классы оболочки Integer, Character, Float, Double. Начиная с версии JDK 5 эта функция, преобразования примитивных типов в эквивалентные объекты, реализована автоматически. Это свойство известно как Автоупаковка(Autoboxing). Обратный процесс соответственно – Распаковка(Unboxing) т.е. процесс преобразования объектов в соответствующие им примитивные типы.
Пример кода для автоупаковки и распаковки представлен ниже:
Автоупаковка
1 Integer integer = 9;
Распаковка
1 int in = 0;
2 in = new Integer(9);
Когда используется автоупаковка и распаковка?
Автоупаковка применяется компилятором Java в следующих условиях:
Cсылка на источник
Для понимания смысла упаковки-распаковки нужно понимать, как работает исполняемая среда и ваша программа на уровне процессора, а так же понимать, что термин ООП это всего лишь надстройка над классическим структурным программированием. Промежуточный байт-код во время выполнения программы преобразуется исполняемой средой в команды конкретного микропроцессора. Есть 3 основных способа хранения, обработки данных и их взаимодействия с программой: процессор-регистр, процессор-стек, и процессор-память. Команды работы с регистрами самые короткие и быстрые, со стеком - короткие, но выполняются на большее число тактов процессора, а команды работы с памятью - самые длинные и медленные. При этом в большинстве случаев простые типы данных хранятся и обрабатываются в регистрах процессора и в стеке, классы и более сложные типы данных хранятся в так называемой "куче" - динамической памяти, которая контролируется исполняемой средой. Механизм кучи достаточно сложен и работа с кучей по времени всегда дольше. Связка стек-регистры максимально эффективна при циклических алгоритмах, где в каждой итерации имеются длинные сложные вычисления, при этом циклический фрагмент кода с регистровой адресацией выполняется в сотни, а то и в десятки тысяч раз быстрее, чем если бы данные хранились в куче:) зато хранение данных в памяти упрощает программу и уменьшает ее размер, а также позволяет использовать все прелести ООП. Упаковку-распаковку придумали для того, чтобы избежать потери производительности программного обеспечения - если критически важна скорость - распаковываем свои данные в простой компактный формат, если скорость не критична - упаковываем в объектный тип и упрощаем программу. Кроме скорости возможна ситуация со значительными затратами ресурсов - к примеру, вам необходимо создать массив из миллиона однобайтовых элементов: что лучше использовать - примитивный однобайтовый тип или упакованный размером в несколько десятков байт?
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Как сделать так чтобы какая та заданная страница сразу открывалась когда запускаешь Spring MVC проект в IntellijIdea?
Такая ситуация, есть репозиторий с проектом, с этим проектом работает разработчик и все работает хорошо
Создаю JTreeДобавляю туда элементы по клику кнопки - тобишь динамически