Java: В чем разница между автобоксом и кастингом? - PullRequest
21 голосов
/ 02 февраля 2009

Этот вопрос касается вопроса «Почему из-за автобокса некоторые вызовы в Java становятся неоднозначными?»

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

Может ли кто-нибудь дать простое объяснение?

Ответы [ 7 ]

35 голосов
/ 02 февраля 2009

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

24 голосов
/ 02 февраля 2009

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

Кастинг - это общий термин с двумя взаимосвязанными, но разными значениями:

  1. Обработка значения одного типа , как если бы это было значение другого типа. Два примера этого первого использования:

    1,1. Учитывая, что класс B расширяет класс A, вы можете запросить myB экземпляр B для обработки как экземпляр A, написав ((A) myB) везде, где ссылка на экземпляр A может появиться. Это фактически не производит новый экземпляр A.

    * * 1.2 1 022. В коллекциях до Java5 весь контент хранился как Object; Обычно для этого требуется использовать приведение после извлечения объекта из коллекции. Например, если вы сохранили String в Map и вам нужно было получить его длину, вы должны написать что-то вроде ((String) myMap.get(someKey)).length(), где приведение будет необходимо для вызова length метода String. Опять же, это не приводит к созданию нового String.
  2. Явно преобразование одного типа в другой (т.е. явное изменение представления). Примером этого второго использования является выражение ((int) (float_var + 0.5F)), которое округляет переменную с плавающей запятой, добавляя 0,5 (что дает значение с плавающей запятой), а затем явно преобразуя это значение в целое число. Результирующее целочисленное значение (после приведения (int)) составляет , полученное из другого значения путем внутренних вычислений.

Приведение может быть выполнено, когда есть отношения суперкласс / подкласс или интерфейс / разработчик (значение 1 выше) или когда два типа являются примитивными числовыми типами (значение 2). Вы можете посмотреть «расширение» и «сужение» для более подробной информации.

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

int      Integer
long     Long
boolean  Boolean
...      ...

Распаковка просто означает получение значения примитива из его обертки объекта.

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

Так что вместо того, чтобы писать (в pre-Java5) что-то вроде:

Map myMap = new HashMap();
...
myMap.put(someKey,Integer.valueOf(3));
...
int nextValue = (myMap.get(someKey)).intValue() + 1;

Вы можете написать:

Map<KeyType,Integer> myMap = new HashMap<KeyType,Integer>();
...
myMap.put(someKey,3);
...
int nextValue = myMap.get(someKey) + 1;

и код упаковки / распаковки вставляется компилятором.

8 голосов
/ 02 февраля 2009
List<String> list = (List<String>)object;

- это актерский состав.

void doSomething(Integer i) { ... }
...
doSomeething(5);

это автобокс.

Integer getSomething();
...
int i = getSomething();

автоматически распаковывается.

4 голосов
/ 02 февраля 2009

Автобокс был введен в Java 5 для предотвращения такого кода, как:

map.put("ABC", new Integer(5));
map.put("DEF", new Integer(6));

Теперь вы можете сказать:

map.put("ABC", 5);

Хотя это проще - у него есть несколько ловушек, если вы не совсем уверены в том, что делаете.

0 голосов
/ 07 января 2013

Можно ли применять автобокс и распаковку в следующем случае?

Long one = 10;
long two = 15;
Long three = 20;

if(one == three) //will this be unboxed or do we need to put a explicit
                 //condition like if(one.intValue() == three.intValue()) 
   System.out.println("Equal");
else 
   System.out.println("Not Equal");  


if(one == two) //will this be unboxed or do we need to put a explicit
               //condition like if(one.intValue() == two) 
   System.out.println("Equal");
else 
   System.out.println("Not Equal");  
0 голосов
/ 02 февраля 2009

Упаковка и распаковка - это тип приведения в Java, где вы приводите примитив к его классу-обёртке или к инверсному, например, от логического значения до логического значения (поле) или от логического значения до логического значения (распаковка).

Типы приведений в Java, например:

  • преобразование личности (§5.1.1) Строка в строку

  • расширение примитивного преобразования (§5.1.2) байт до целого

  • сужение примитивного преобразования (§5.1.3) int to byte

  • расширение эталонного преобразования (§5.1.5) Целое число

  • сужение эталонного преобразования (§5.1.6) Число в целое число

  • преобразование бокса (§5.1.7) целое число в целое число

  • преобразование без распаковки (§5.1.8). Целое число в int

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

0 голосов
/ 02 февраля 2009

Бокс заключает в себе значение внутри контейнера, например, примитивное значение int внутри объекта Integer

Кастинг - это как посмотреть на тип.

Первый производит другой тип значения, второй просто изменяет способ обработки уже существующего значения

За исключением того, что приведение между примитивными типами фактически изменяет их представление. (Это не проясняет, не так ли?)

...