【问题标题】:What is the difference between double a = a + int b and int a += double b?double a = a + int b 和 int a += double b 有什么区别?
【发布时间】:2010-10-11 03:48:05
【问题描述】:

为什么会这样:

public class Addition { 
  public static void main() { 
    int a = 0; 
    double b = 1.0; 
    a = a + b;
    System.out.println(a); 
  }
}

不编译但是:

public class Addition { 
  public static void main() { 
    int a = 0; 
    double b = 1.0; 
    a += b; 
    System.out.println(a); 
  }
}

编译。

【问题讨论】:

    标签: java types type-conversion operators implicit-conversion


    【解决方案1】:

    int = int + double 本质上是

    int = 双倍 + 双倍

    如果不进行强制转换,您将无法做到这一点......

    int += double 将结果强制转换为 int,而另一个则需要强制转换。

    所以 a = (int)(a + b);

    应该编译。

    编辑:根据 cmets 的要求...这里是更多阅读的链接(不是最简单的阅读,而是最正确的信息):http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.26.2

    【讨论】:

    • 您能否提供一些链接以供进一步阅读?谢谢
    • 我认为“深层”的原因是因为在缩小时不允许分配:byte = int 是不允许的,int = double 也是如此。会做一个简单的字节a吗?一个 += 2;如果编译失败,人们会向 java 扔鞋。但我仍然希望在没有演员阵容的情况下使用额外的规则:(
    • 我不确定是否有深层原因,但 Java 语言规范明确定义了隐式转换:java.sun.com/docs/books/jls/second_edition/html/…
    【解决方案2】:

    正如大家已经说过的,+= 有一个隐式转换。为了帮助说明这一点,我将使用我不久前编写的一款非常适合这类问题的应用程序。这是一个在线反汇编程序,因此您可以查看正在生成的实际字节码:http://javabytes.herokuapp.com/

    以及它们的含义表: http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings

    那么让我们来看看一些简单的Java代码的字节码:

    int i = 5;
    long j = 8;
    i += j;
    

    反汇编代码。我的 cmets 前面会有一个 //。

       Code:
            0: iconst_5  //load int 5 onto stack
            1: istore_0  //store int value into variable 0 (we called it i)
            2: ldc2_w #2; //long 8l
                         //load long 8 value onto stack.  Note the long 8l above
                         //is not my comment but how the disassembled code displays 
                         //the value long 8 being used with the ldc2_w instruction
            5: lstore_1  //store long value into variable 1 (we called it j)
            6: iload_0   //load int value from variable 0
            7: i2l       //convert int into a long.  At this point we have 5 long
            8: lload_1   //load value from variable 1
            9: ladd      //add the two values together.  We are adding two longs
                         //so it's no problem
            10: l2i      //THIS IS THE MAGIC.  This converts the sum back to an int
           11: istore_0  //store in variable 0 (we called it i)
    

    【讨论】:

      【解决方案3】:

      double + int 返回双精度,所以 double = double + int 是合法的,请参阅 JLS 5.1.2 Widening Primitive Conversion 另一方面 int = double + int 是“Narrowing Primitive Conversion”,需要显式转换

      【讨论】:

        【解决方案4】:

        在 Java 中,+= 运算符隐式转换为左侧类型。这适用于所有组合运算符。

        【讨论】:

        • 我认为这是一个更简洁的答案