Что значит сказать, что тип является «коробочным»? - PullRequest
39 голосов
/ 13 сентября 2009

Я слышал о типах, которые в некоторых языках называются «коробочными».

В Java я слышал об "автобоксе". Что это? У него есть классы-обертки для типа? Как изменится мой код, если я работаю с коробочными или распакованными типами?

Ответы [ 6 ]

54 голосов
/ 13 сентября 2009

Некоторые типы данных считаются «примитивными», то есть они не обрабатываются как объект и не имеют свойств объекта.

На большинстве платформ целые числа и символы являются примерами типов, которые являются примитивными, но могут быть в штучной упаковке.

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

Точное значение и поведение зависят от языка, который вы используете. Некоторые языки (такие как Smalltalk ... по крайней мере, когда я это делал ...) не допускают никаких примитивных типов и считают все объектом, но с этим связано снижение производительности, потому что в конце дня процессор должен работать с необработанными числами и необработанной памятью, чтобы выполнять полезную работу. Если вы хотите добавить два целых числа, которые были упакованы, например, за кулисами, они «распакованы» в примитивные типы, числа добавляются, и они затем помещаются обратно в новое целое число.

16 голосов
/ 13 сентября 2009

Более конкретная информация для Java:

Автобокс позволяет java автоматически конвертировать такие вещи, как boolean и int в их версии объектов Boolean и Integer, в большинстве случаев автоматически. Это также позволяет происходить обратному.

Например:

int a = 3; // no boxing is happening
Integer b = 3;  // newer versions of java automatically convert the int 3 to Integer 3
int c = b;  // these same versions also automatically convert Integer 3 to int 3

В старых версиях java, в которых отсутствует автобокс, этот код должен делать то же самое:

int a = 3;  // works the same
Integer b = new Integer(3);  //must set up a Integer object manually
int c = b.intValue(); //must change Integer object to a primitive

Однако есть некоторые сценарии, в которых вам все равно придется что-то делать вручную. Например, представьте, что у вас есть класс с двумя методами, такими как:

assertEquals(int a, int b);
assertEquals(Object a, Object b)

Теперь, если вы попытаетесь сделать это:

Integer a = 3;
int b = 3;
assertEquals(a, b);  // this will not compile

Причина, по которой это не работает, заключается в том, что он не может определить, нужно ли ему распаковывать a в int или в поле b в Integer. Поэтому неоднозначно, какой метод подписи должен быть вызван. Чтобы это исправить, вы можете сделать одно из следующих действий:

assertEquals((int) a, b);
assertEquals(a, (Integer) b);
12 голосов
/ 13 сентября 2009

Да, бокс означает взятие типа значения и оборачивание его в ссылочный тип. Так как в Java введен автобокс, вы можете сделать:

void foo(Object bar) {}
//...
    foo(1);

И Java автоматически превратит int 1 в целое число. В предыдущих версиях вам нужно было сделать:

foo(new Integer(1));

Автобокс наиболее полезен в java при работе с обобщениями, поскольку вы не можете использовать примитивы с обобщениями, поэтому для хранения целых чисел в списке вам нужно создать List<Integer> и поместить вставки в список .

3 голосов
/ 13 сентября 2009

Тип в штучной упаковке означает, что значения размещаются в блоке в куче и ссылаются через указатель. Это хорошо для единообразия в реализации среды выполнения (упрощает использование универсальных функций и т. Д.) За счет дополнительного косвенного обращения.

0 голосов
/ 13 сентября 2009

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

0 голосов
/ 13 сентября 2009

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

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

...