2013-05-31 2 views
2

В какой-то код, который я вижу это:Распаковка Long в Java

private void compute(Long a, Long b, Long c) { 
     long result = a-(b+c); 
... 

Это кажется немного странным, что результат сохраняется в первобытном длинной вместо объекта Long, соответствующие операнды.

Есть ли причина, по которой результат должен храниться как примитив?

+3

Более серьезный вопрос: почему 'Long' был использован вообще. Это намного менее эффективно. –

+0

Он хранится как примитив, потому что вы заявили его как примитив. – enkor

+0

Возможно, вы найдете некоторые подсказки здесь [link] (http://stackoverflow.com/questions/239560/when-should-i-use-primitives-instead-of-wrapping-objects) – PbxMan

ответ

0

Основываясь на ваших потребностях. Я подразумеваю замедление.

Autoboxing и unboxing может произойти в любом месте, где объект, как ожидается, и примитивный тип доступен

1

Причина очевидна: результат объявлен как примитивный.

+1

На самом деле это не причина. –

+0

Я не понимаю, почему это не причина. Если под «результатом» вы понимаете объявленную переменную, то это и есть причина. Если под «результатом» вы понимаете результат операции «a- (b + c)», то причина в том, что операция добавления определена для примитивов, и именно поэтому Longs автоматически распаковываются перед добавлением. – nakosspy

0

Обычно вам следует использовать примитивы, особенно если вы уверены, что они не могут быть пустыми. Если вы настаиваете на том, чтобы использовать типы в штучной упаковке, всегда думайте о том, что происходит, когда оно равно null. Java будет делать бокс и распаковку автоматически для вас, но глядя на int и задаваясь вопросом, почему вы получили исключение NullPointerException, может быть интересно.

0

Начиная с версии Java 1.5 автобоксинг и распаковка происходит неявно, когда это необходимо.

0

Следующая строка:

long result = a-(b+c); 

... просит Java взять результат выражения с использованием 3 Long с, а затем сохранить его в примитивное долго. Перед Java 5 он жаловался на типы, не совпадающие - но в наши дни он просто предполагает, что вы имеете в виду то, что вы говорите, и автоматически выполняет преобразование из объекта в примитивный тип для вас.

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

3

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

Нет, что «странно», что вы можете использовать + и - операторов на протяженных объектах. Перед Java 5 это было бы синтаксической ошибкой. Затем была введена автобоксинг/распаковка. То, что вы видите в этом коде, - autounboxing: операторы требуют примитивов, поэтому компилятор автоматически вставляет вызов longValue() на объекты. Затем арифметика выполняется на примитивных значениях long, и результат также является long, который может быть сохранен без дальнейшего преобразования переменной.

Что касается почему код делает это, реальный вопрос, почему кто-то будет использовать Long тип вместо long. Возможные причины:

  • Значения получены из библиотеки/API, которая обеспечивает значения Long.
  • Значения хранятся в коллекциях (List, Map), которые не могут содержать примитивы.
  • Sloppiness или cargo cult programming.
  • Требуется значение null, например. для передачи недоступных или неинициализированных данных.

Обратите внимание, что способность Long держать null значения означает, что вычисление (или более конкретно, longValue() вызовов, вставленные компилятор) может потерпеть неудачу с NullPointerException - возможностью код должен иметь дело с каким-то образом.

0

В соответствии с javadoc

Boxing conversion converts expressions of primitive 
type to corresponding expressions of reference type. 
Specifically, the following nine conversions are called the boxing conversions: 

From type boolean to type Boolean 

From type byte to type Byte 

From type short to type Short 

From type char to type Character 

From type int to type Integer 

From type long to type Long 

From type float to type Float 

From type double to type Double 

From the null type to the null type 


Ideally, boxing a given primitive value p, would always yield an identical reference.  
In practice, this may not be feasible using existing implementation techniques. The 
rules above are a pragmatic compromise. The final clause above requires that certain 
common values always be boxed into indistinguishable objects. The implementation may 
cache these, lazily or eagerly. For other values, this formulation disallows any 
assumptions about the identity of the boxed values on the programmer's part. This would 
allow (but not require) sharing of some or all of these references. 

This ensures that in most common cases, the behavior will be the desired one, without  
imposing an undue performance penalty, especially on small devices. Less memory-limited 
implementations might, for example, cache all char and short values, as well as int and 
long values in the range of -32K to +32K.` 

Here is the Oracle Doc source

0

Арифметические операторы + и - не определены для штучных типов (например, в длине), но для примитивных типов (например, длинных).

Результат также длинный. См. Autoboxing and Unboxing tutorial

Автобоксирование этого в длинное приведет к небольшой стоимости исполнения. Это также не нужно, потому что

  1. Мы знаем, что это будет непустым (если a, b или c были пустыми, возникло бы исключение NullPointerException).
  2. Это будет автоматически запрещено, если мы будем использовать его позже, когда требуется Long.
Смежные вопросы