Java: Какая разница между автобоксингом и литьем?
Этот вопрос посвящен "Почему автобоксинг делает некоторые вызовы неоднозначными в Java?"
Но, читая ответы, есть несколько ссылок на кастинг, и я не уверен, что полностью понимаю разницу.
Может ли кто-нибудь дать простое объяснение?
Ответы
Ответ 1
Бокс - это когда вы конвертируете примитивный тип в ссылочный тип, а не бокс - наоборот. Кастинг - это когда вы хотите, чтобы один тип рассматривался как другой тип, между примитивными типами и ссылочными типами, это подразумевает неявную или явную операцию бокса. Является ли оно явным, является языковой функцией.
Ответ 2
Как литье, так и бокс/распаковка имеют отношение к типам и кажущему (или реальному) преобразованию, но бокс /unboxing специфичен для отношения между примитивными типами и их соответствующими типами обертки, тогда как литье - это термин для явного или неявного изменения типа в более общем смысле.
Литье - это общий термин с двумя связанными друг с другом значениями:
-
Обработка значения одного типа , как если бы, это значение другого типа. Два примера этого первого использования:
1,1. Учитывая, что класс B
расширяет класс A
, вы можете запросить myB
экземпляр B
для обработки как экземпляр A
путем записи ((A) myB)
везде, где ссылка на экземпляр A
может появиться. Это фактически не создает новый экземпляр A
.
1,2. Коллекции Pre-Java5 сохраняли все содержимое как Object
; обычно требуется, чтобы вы использовали бросок после извлечения объекта из коллекции. Например, если вы сохранили String
в Map
и должны были получить его длину, вы должны написать что-то вроде ((String) myMap.get(someKey)).length()
, где для приведения в действие нужно было бы использовать метод length
String
. Опять же, это не создает новый String
.
-
Явно преобразование одного типа в другой (т.е. явное изменение представления). Примером этого второго использования является выражение ((int) (float_var + 0.5F))
, которое округляет переменную с плавающей запятой, добавляя 0.5 (что дает значение с плавающей запятой), а затем явно преобразует это значение в целое число. Полученное целочисленное значение (после приведения (int)
) получается из другого значения путем внутренних вычислений.
Кастинг может выполняться при наличии отношения суперкласса/подкласса или интерфейса/реализации (значение 1 выше) или когда два типа являются примитивными числовыми типами (значение 2). Вы можете посмотреть "расширение" и "сужение" для более подробной информации.
Бокс относится к обертыванию примитивных типов в контейнерных объектах, как правило, выполняется только тогда, когда у вас должен быть объект (например, сохранение значения в коллекции). Типы примитивов и оболочек попадают парами:
int Integer
long Long
boolean Boolean
... ...
Unboxing просто означает получение примитивного значения из его оболочки объекта.
Начиная с Java5, когда вы пишете выражение, в котором используется примитивное значение, где потребуется соответствующий тип-оболочка (например, помещение целого в коллекцию), компилятор автоматически сползает в коде, который фактически обертывает это примитивное значение. Аналогичным образом он предоставит вам развернутый код.
Итак, вместо написания (в пред-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;
а код бокса/распаковки вставляется компилятором.
Ответ 3
List<String> list = (List<String>)object;
- это литье.
void doSomething(Integer i) { ... }
...
doSomeething(5);
- автоматический бокс.
Integer getSomething();
...
int i = getSomething();
является автоматической распаковкой.
Ответ 4
Автообъект был введен в Java 5 для предотвращения использования кода, например:
map.put("ABC", new Integer(5));
map.put("DEF", new Integer(6));
Теперь вы можете сказать:
map.put("ABC", 5);
Хотя это проще - у него есть несколько подводных камней, если вы не совсем уверены в том, что делаете.
Ответ 5
Бокс обертывает значение внутри контейнера, например, примитивное значение int внутри объекта Integer
Кастинг - это как посмотреть тип.
Первое производит другое значение, позже просто изменяет способ обработки уже существующего значения
Кроме того, что литье между примитивными типами фактически изменяет их представление. (Это не делает это яснее?)
Ответ 6
Бокс и unboxing - это тип трансляции на Java, где вы отбрасываете из примитива в его класс-оболочку или обратно, например. boolean to Boolean (box) или Boolean для boolean (unbox).
Типы приведений в Java, например:
-
преобразование идентичности (п. 5.1.1)
String to String
-
расширяющееся примитивное преобразование (§5.1.2)
byte to int
-
сужение примитивного преобразования (§5.1.3)
int to byte
-
расширяющееся ссылочное преобразование (§5.1.5)
Целое число в число
-
сужение эталонного преобразования (п. 5.1.6)
Number to Integer
-
конверсия бокса (§5.1.7)
int to Integer
-
преобразование для распаковки (п. 5.1.8).
Целое число в int
Автобоксирование или аутообъявление происходит, когда компилятор выполняет преобразование бокса/распаковки для вас (он явно не отображается в исходном коде как выражение для трансляции), например. см. вопрос, на который вы ссылались.
Ответ 7
Можно ли применять Autoboxing и Unboxing в следующем случае?
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");