2009-02-01 12 views
21

This question о «Почему автобоксинг делает некоторые вызовы неоднозначными в Java?»Java: В чем разница между автобоксингом и литьем?

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

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

+0

http://java.sun.com/docs/books/jls/third_edition/html/conversions.html выглядит полезным –

ответ

33

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

+2

Я считаю, что это правильный ответ, но я не думаю, что бокс/unboxing следует описывать как «преобразование». Можно было бы уточнить, что примитив завернут в эквивалентный объект. –

+0

@ Outlaw Programmer: Я согласен, это было бы более точно. – cmsjr

+0

любой пример? , – Faizan

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

отлит.

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

- авто-бокс.

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

- авто-распаковка.

+1

Ключевым моментом здесь является то, что Integer является ссылочный тип и Int (или цифра 5) это тип значения/примитив. –

+2

Ваш второй пример - авто-бокс, если бы вы правильно произвели «doSomething» ..... –

3

Autoboxing был введен в Java 5, чтобы предотвратить такой код:

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

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

map.put("ABC", 5); 

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

0

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

Casting просто как смотреть на тип.

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

Кроме литья между примитивными типами фактически изменяет их представление. (Это не делает это яснее?)

0

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

Типы отливок в Java, с, например:

  • конверсии идентичности (§5.1.1) Строка Строка

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

  • сужению примитивные преобразования (§5.1.3) INT в байте

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

  • ссылка Сужение преобразования (§5.1.6) Номер для Integer

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

  • распаковка преобразования (§5.1.8). Integer в целое

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

24

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

Casting является общим термином, с двумя связанными, но-разными значениями:

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

    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.

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

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

Бокс относится к обертывающим примитивным типам в контейнерных объектах, как правило, только при наличии объекта (например, хранения значения в коллекции).Исходный и обертка типа приходит пары:

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; 

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

+0

Очень красиво описано. Примеры ftw! – sector7

0

Можно ли использовать Autoboxing and 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"); 
+0

во время 2-го теста на равенство, авто-распаковка происходит с примитивным типом [Измененный код работает здесь] (http://ideone.com/R228Q6) – Abhijeet

 Смежные вопросы

  • Нет связанных вопросов^_^