java如何允许添加Integer和Double实例?

时间:2017-07-16 21:03:17

标签: java wrapper

执行以下代码时,第3行内部发生了什么

Integer i=1; 
Double d1=1.1; 
Double d2= i+d1;

3 个答案:

答案 0 :(得分:10)

您可以在语言规范中阅读“内部”工作的定义:

但这些可能有点干。

尝试反编译以下代码:

void add(Integer i, Double d1) {
  Double d2= i+d1;
}

编译为:

  void add(java.lang.Integer, java.lang.Double);
    Code:
       0: aload_1
       1: invokevirtual #6                  // Method java/lang/Integer.intValue:()I
       4: i2d
       5: aload_2
       6: invokevirtual #7                  // Method java/lang/Double.doubleValue:()D
       9: dadd
      10: invokestatic  #5                  // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      13: astore_3
      14: return

逐行分解(对于重要的行,无论如何):

  • 1:这是从iInteger
  • 的取消装箱int
  • 4:这会将int的{​​{1}}值扩大为i
  • 6:这是从doubled1
  • 的取消装箱Double
  • 9:这是添加未装箱(和加宽)的值。
  • 10:这是将double的结果装箱到double

您可以将其视为等同于:

Double

因为两者具有相同的字节码。

答案 1 :(得分:2)

在Java中的每个算术运算中,结果至少为int。如果任何操作数大于int,则结果与较大操作数的类型相同。在第三行,我被取消装箱并提升为双倍,并添加到未装箱的d1值。然后将结果装入d2。

答案 2 :(得分:1)

  

java如何允许添加Integer和Double实例?

包装器对象(整数,双精度,浮点数等)不能是+-等算术运算符的直接目标。 只有原语可能是这些运算符的目标。

但是从java 5开始,Java允许自动将Integer转换为int并使用自动装箱进行反向。

所以这里:

Integer i=1; 
Double d1=1.1; 
Double d2= i+d1;

第三行可分为两个步骤:

  • i+d1Double d1Integer i转换为对应的原语(拆箱操作)。这允许进行添加(1 + 1.1)以产生double原始值。

  • 此处Double d2=i+d1;double原语的结果将转换为Double对象(装箱)。