++运算符对整数有什么作用?

时间:2018-12-17 10:15:35

标签: java variable-assignment wrapper

以下测试用例将通过:

@Test
public void assignWrapperTest() {
    System.out.printf("\nassign - %s\n", "wrapper");

    Integer a = 1000;
    Integer b = a;
    System.out.printf("a = %d, b = %d\n", a, b);
    Assert.assertEquals(a, b);
    Assert.assertSame(a, b); // a, b are the same object,

    a++;
    System.out.printf("a = %d, b = %d\n", a, b);
    Assert.assertNotEquals(a, b);
    Assert.assertNotSame(a, b); // a, b are not the same object, any more,
}

所以:

  • a++更改。
  • b保持不变。

问题是:

  • b = a只是给参考值赋权,它们指向的是同一个对象,此时只有一个对象,对吧?
  • 什么是整数运算符?
    由于Integer是不可变的,这是否意味着++创建了一个新的Integer对象,并将其自动分配回原始变量?如果是这种情况,这是否意味着a现在指向另一个对象?
  • 现在有2个对象?并且b仍指向原始位置吗?

5 个答案:

答案 0 :(得分:10)

a++;

由于aInteger,因此与以下内容相同:

a = Integer.valueOf(a.intValue() + 1);
  

这是否意味着++创建了一个新的Integer对象

也许(但不一定):Integer.valueOf将重用缓存的值;仅当超出缓存范围(至少-128..127)时,才会创建一个新值。

答案 1 :(得分:4)

如果我们看Byte code的{​​{1}},如下图所示:

a++

所以指令就像获得 9: aload_1 10: invokevirtual #22 // Method java/lang/Integer.intValue:()I 13: iconst_1 14: iadd 15: invokestatic #16 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 18: astore_1 中的intValue(),然后a,然后对增量值调用increment,然后Integer#valueOf创建一个新对象。

答案 2 :(得分:1)

  • 那是正确的。这就是JVM的工作方式。
  • 是的。 a++有效地执行了a=a+1(忽略了将其转换为Integer的逻辑)。表达式a+1的结果为一个新的int,该表达式被分配给a
  • 是的。 b的值尚未被先前的操作所触及,因此它仍指向同一对象。

答案 3 :(得分:1)

是的

Integer对象是不可变的。但是,他们持有的引用是可变的。 Integer类,缓存数据并重用它们。

让我们看看您的代码中发生了什么。

Integer a = 1000; //假设它在堆中创建了一个4字节的内存块,地址引用为&addr_of_val_1000;

Integer b = a; //现在,b指向地址引用&addr_of_val_1000;

a++; //这会在堆中/从堆中创建/获取新值1001,并使用新的地址引用&addr_of_val_1001;并将其分配给变量a

所以

a = 1001和b = 1000不相等。 &addr_of_val_1000!=&addr_of_val_1001(它们的引用不再相同)

但是,如果您添加

b++;

b = Integer.valueOf(1001)

在您进行检查之前,它们将是相同的并且再次相同。

答案 4 :(得分:0)

关键是Integerimmutable

  1. 如果操作数是可变的,例如int++运算符,只需将1添加到原始值

  2. 对于Integer,这是不同的。通过a++,创建了Integer的新实例,其值来自于将1和{{1}都添加到原始Integer对象中}指向,然后将a重新分配给该新对象。 b仍引用原始的Integer对象,因此ab现在不相同。