在Java中取消装箱长

时间:2013-05-31 10:30:44

标签: java arithmetic-expressions

在某些代码中,我看到了这一点:

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

结果存储在原始的 long 而不是与其操作数对应的 Long 对象中,这似乎有点奇怪。

是否有任何理由将结果存储为基元?

9 个答案:

答案 0 :(得分:5)

  

结果存储在原始long而不是与其操作数对应的Long对象中似乎有点奇怪。

不,“奇怪”是你可以在Long对象上使用+-运算符。在Java 5之前,这可能是语法错误。然后引入了自动装箱/拆箱。您在此代码中看到的是autounboxing:运算符需要初始化,因此编译器会自动在对象上插入对longValue()的调用。然后对原始long值执行算术,结果也是long,可以存储而无需对变量进行进一步转换。

至于为什么代码执行此操作,真正的问题是为什么有人会使用Long类型而不是long。可能的原因:

  • 值来自某些提供Long值的库/ API。
  • 这些值存储在集合(ListMap)中,这些集合无法保存基元。
  • Sloppiness或cargo cult programming
  • 需要具有null值的功能,例如发出不可用或未初始化数据的信号。

请注意,Long保留null值的能力意味着计算(或更具体地说,编译器插入的longValue()调用)可能会因NullPointerException而失败 - 代码应该以某种方式处理的可能性。

答案 1 :(得分:1)

原因很明显:结果被声明为原始。

答案 2 :(得分:0)

根据您的需要。我的意思是去除。

Autoboxingunboxing可以发生在预期对象和原始类型可用的任何地方

答案 3 :(得分:0)

通常你应该更喜欢使用原语,特别是如果你确定它们不能为空。如果你坚持使用盒装类型,总是要考虑当它为空时会发生什么。 Java会自动为你做装箱和拆箱,但是盯着一个int并想知道你为什么得到NullPointerException会很有趣。

答案 4 :(得分:0)

从Java 1.5开始,无论何时需要,都会隐式发生自动装箱和拆箱。

答案 5 :(得分:0)

以下一行:

long result = a-(b+c);

...要求Java使用3 Long s获取表达式的结果,然后将其存储在原始long中。在Java 5之前,它会抱怨不匹配的类型 - 但是现在它只是假设你的意思是你所说的并自动为你做从对象到原始类型的转换。

在这个例子中,除非这里没有其他一些好的理由,否则首先将参数作为盒装对象类型绝对没有意义。

答案 6 :(得分: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

答案 7 :(得分:0)

算术运算符+和 - 不是为盒装类型(例如Long)定义的,而是针对基本类型(例如long)定义的。

结果也很长。见Autoboxing and Unboxing tutorial

将其自动装入Long会导致性能成本降低。这也是不必要的,因为

  1. 我们知道它将是非null(如果a,b或c为null,则会发生NullPointerException)。
  2. 如果我们稍后在需要Long的地方使用它,它将被隐式自动装箱。

答案 8 :(得分:-1)

您的疑问的答案是

  1. Java中的自动装箱和自动拆箱,它们分别从原始类对象转换为包装类对象,反之亦然。
  2. 自动装箱意味着内部编译器使用原始类的valueOf()方法,而自动拆箱意味着内部编译器使用xxxValue()方法。
  3. 假设 私有无效计算(Long a,Long b,Long c){     长结果= a-(b + c);

它进行了这种转换 a.longValue()-(b.longValue()+ c.longValue()) 这意味着即使在您的语句执行加法运算之前,编译器也会将long类型的原语提供为操作数的输入 请记住,这与JAVA是静态和强类型语言有关。

因此您将获得长类型输出

我希望我清除了您的疑问