Java - Язык:В чем разница между автоматической упаковкой и кастингом?

StackOverflow https://stackoverflow.com/questions/501653

  •  20-08-2019
  •  | 
  •  

Вопрос

Этот вопрос речь идет о том, "Почему автобоксинг делает некоторые вызовы неоднозначными в Java?"

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

Кто-нибудь может дать простое объяснение?

Это было полезно?

Решение

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

Другие советы

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

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

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

    1.1.Учитывая этот класс B расширяет класс A, вы можете попросить myB пример того , что B рассматриваться как экземпляр A написав ((A) myB) везде, где есть ссылка на экземпляр A может появиться.На самом деле это не приводит к созданию нового экземпляра A.

    1.2.Коллекции, созданные до Java5, хранили весь контент как Object;обычно для этого требовалось использовать приведение после извлечения объекта из коллекции.Например, если бы вы сохранили String в Map и нужно было получить его длину, вы бы написали что-то вроде ((String) myMap.get(someKey)).length() где приведение потребовалось бы для того, чтобы вызвать length способ String.Опять же, это не вызывает нового String быть созданным.

  2. Явно преобразование от одного типа к другому (т.е.явное изменение представления).Пример этого второго использования содержится в выражении ((int) (float_var + 0.5F)) который округляет переменную с плавающей запятой путем добавления 0,5 (что дает значение с плавающей запятой), а затем явно преобразует это значение в целое число.Результирующее целочисленное значение (после (int) актерский состав) является произведенный из другого значения путем внутреннего вычисления.

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

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

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

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

Начиная с 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;

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

List<String> list = (List<String>)object;

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

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

это автоматический бокс.

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

происходит автоматическая распаковка коробки.

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

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

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

map.put("ABC", 5);

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

Упаковка - это перенос значения внутрь контейнера, такого как примитивное значение int внутри целочисленного объекта

Кастинг - это просто способ взглянуть на типаж.

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

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

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

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

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

  • расширяющееся примитивное преобразование (§5.1.2) байт в int

  • упрощенное преобразование с сужением (§5.1.3) int в байт

  • расширяющееся преобразование ссылки (§5.1.5) Целое число в число

  • преобразование сужающейся ссылки (§5.1.6) Число в целое

  • преобразование пакета (§5.1.7) из int в Integer

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

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

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

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");  
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top