2

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

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

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

是否有任何理由将结果存储为原语?

4

9 回答 9

5

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

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

至于代码为什么这样做,真正的问题是为什么有人会使用Longtype 而不是long. 可能的原因:

  • 这些值来自一些提供Long值的库/API。
  • 这些值存储在不能保存原语的集合 ( List, ) 中。Map
  • 马虎或货物崇拜编程
  • 需要具有null值的能力,例如表示不可用或未初始化的数据。

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

于 2013-05-31T10:57:47.593 回答
1

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

于 2013-05-31T10:33:21.867 回答
1

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

结果也长了。请参阅自动装箱和拆箱教程

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

  1. 我们知道它将是非空的(如果 a、b 或 c 为空,则会发生 NullPointerException)。
  2. 如果我们稍后在需要 Long 的地方使用它,它将被隐式自动装箱。
于 2013-05-31T11:05:08.620 回答
0

以下行:

long result = a-(b+c);

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

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

于 2013-05-31T10:48:36.747 回答
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.`

这是 Oracle 文档源

于 2013-05-31T10:58:36.223 回答
0

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

于 2013-05-31T10:34:09.293 回答
0

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

于 2013-05-31T10:34:31.533 回答
0

根据您的需求。我的意思是declaration。

Autoboxing并且unboxing可以发生在需要对象且原始类型可用的任何地方

于 2013-05-31T10:32:55.410 回答
-1

你的疑惑的答案是

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

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

因此你得到长类型输出

我希望我消除了你的疑虑

于 2019-05-16T19:20:14.590 回答