【问题标题】:Unboxing Long in java在java中拆箱长
【发布时间】:2013-05-27 03:42:02
【问题描述】:

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

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

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

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

【问题讨论】:

  • 一个更严重的问题是为什么Long 一直被使用。它的效率要低得多。
  • 它被存储为原语,因为您已将其声明为原语。
  • 或许你可以在这里找到一些线索link
  • @dmiller2117 我想他的意思是他正在阅读别人的代码并想知道为什么这个人在那里使用原始类型。
  • 一个 void 方法有一个名为“result”的局部变量也很有趣......但我想这意味着别的东西:P

标签: java arithmetic-expressions


【解决方案1】:

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

Autoboxingunboxing 可以出现在需要对象且原始类型可用的任何地方

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 其实不是这个原因。
    • 我不明白为什么这不是原因。如果在“结果”下您理解了声明的变量,那么这就是原因。如果在“结果”下你理解了“a-(b+c)”操作的结果,那么原因是加法操作是为基元定义的,这就是Longs在添加之前自动拆箱的原因。跨度>
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        下面一行:

        long result = a-(b+c);
        

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

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

        【讨论】:

          【解决方案6】:

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

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

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

          • 这些值来自一些提供Long 值的库/API。
          • 值存储在集合(ListMap)中,不能保存原语。
          • 草率或cargo cult programming
          • 需要具有null 值的能力,例如表示不可用或未初始化的数据。

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

          【讨论】:

            【解决方案7】:

            根据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

            【讨论】:

              【解决方案8】:

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

              结果也很长。见Autoboxing and Unboxing tutorial

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

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

              【讨论】:

                【解决方案9】:

                你的疑惑的答案是

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

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

                因此你得到长类型输出

                我希望我消除了你的疑虑

                【讨论】:

                • 嘿,首先你的答案并不是真正的答案,因为你在这里解释的机制(autoboxing & unboxing),将Long对象转换为long原语,也可以如果结果是Long result = a-(b+c);,则将结果转换为Long 对象。其次也是最后一点,您的帖子格式不正确,1/2/3 结构完全没有意义。
                • 当然先生,如果您声称这是错误的,那么请用正确的分析来启发我。如果 Long 结果出现,那么将再次出现自动装箱步骤
                • 我不会,因为那不是我来这里的原因。我只是在回顾迟到的答案。我只是说您的答案没有帮助,因为它只是说与迈克尔·博格沃特(Michael Borgwardt)的答案相同,该答案与问题在同一天发布。但他的格式更好,解释/开发。如果您想帮助他人,请回答需要回答的问题,并关心其有用性和格式。
                • 感谢您的回复。将来一定会采纳您的建议
                猜你喜欢
                • 2011-08-29
                • 1970-01-01
                • 1970-01-01
                • 2022-06-16
                • 2011-03-13
                • 1970-01-01
                • 2011-05-02
                • 2015-02-23
                相关资源
                最近更新 更多