++ 运算符对整数有什么作用?
What does the ++ operator do to an Integer?
以下测试用例将通过:
@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
还是指向原来的那个?
a++;
因为 a
是一个 Integer
,这等同于:
a = Integer.valueOf(a.intValue() + 1);
does this means ++
created a new Integer object
可能,但不一定:Integer.valueOf
将重用缓存值;只有在缓存范围之外(至少为 -128..127)才会创建新值。
如果我们看a++
的Byte code
;它看起来像下面这样:
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
所以指令就像获取 a
的 intValue()
然后 increment
它然后调用 Integer#valueOf
增量值和 Integer#valueOf 创建一个新对象。
- 没错。这就是 JVM 的工作方式。
- 是的。
a++
有效地执行 a=a+1
(忽略将其转换为 Integer
的逻辑)。表达式 a+1
的计算结果是一个新的 int
,并且它被分配给 a
.
- 肯定的。
b
的值没有被前面的操作触及,因此它仍然指向同一个对象。
这里的重点是Integer
是immutable
.
如果操作数是可变的,比如 int
,++
运算符只需将 1
添加到原始值 中 .
对于Integer
是不同的。通过a++
,创建了一个新的Integer
实例,它的值来自于在a
和b
的原始Integer对象上增加了一个1
] 指向,然后 a
被重新分配给这个新对象。 b
仍然引用原来的 Integer 对象,所以 a
和 b
现在不一样了。
是的。
Integer
对象是不可变的。但是,它们持有的引用是可变的。
Integer
类,缓存数据并重复使用。
让我们看看您的代码中发生了什么。
Integer a = 1000;
// 假设它在堆中创建一个 4 字节的内存块,地址引用 &addr_of_val_1000;
Integer b = a;
// 现在,b 指向地址引用 &addr_of_val_1000;
a++;
// 这个 creates/fetches 一个新值 1001
in/from 具有新地址引用的堆 &addr_of_val_1001;
并分配给变量 a
所以,
a = 1001 和 b = 1000 不相等。
&addr_of_val_1000 != &addr_of_val_1001 (它们的引用不再相同)
但是,如果你加上,
b++;
或
b = Integer.valueOf(1001)
在你检查之前,它们将再次相等。
以下测试用例将通过:
@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
还是指向原来的那个?
a++;
因为 a
是一个 Integer
,这等同于:
a = Integer.valueOf(a.intValue() + 1);
does this means
++
created a new Integer object
可能,但不一定:Integer.valueOf
将重用缓存值;只有在缓存范围之外(至少为 -128..127)才会创建新值。
如果我们看a++
的Byte code
;它看起来像下面这样:
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
所以指令就像获取 a
的 intValue()
然后 increment
它然后调用 Integer#valueOf
增量值和 Integer#valueOf 创建一个新对象。
- 没错。这就是 JVM 的工作方式。
- 是的。
a++
有效地执行a=a+1
(忽略将其转换为Integer
的逻辑)。表达式a+1
的计算结果是一个新的int
,并且它被分配给a
. - 肯定的。
b
的值没有被前面的操作触及,因此它仍然指向同一个对象。
这里的重点是Integer
是immutable
.
如果操作数是可变的,比如
int
,++
运算符只需将1
添加到原始值 中 .对于
Integer
是不同的。通过a++
,创建了一个新的Integer
实例,它的值来自于在a
和b
的原始Integer对象上增加了一个1
] 指向,然后a
被重新分配给这个新对象。b
仍然引用原来的 Integer 对象,所以a
和b
现在不一样了。
是的。
Integer
对象是不可变的。但是,它们持有的引用是可变的。
Integer
类,缓存数据并重复使用。
让我们看看您的代码中发生了什么。
Integer a = 1000;
// 假设它在堆中创建一个 4 字节的内存块,地址引用 &addr_of_val_1000;
Integer b = a;
// 现在,b 指向地址引用 &addr_of_val_1000;
a++;
// 这个 creates/fetches 一个新值 1001
in/from 具有新地址引用的堆 &addr_of_val_1001;
并分配给变量 a
所以,
a = 1001 和 b = 1000 不相等。 &addr_of_val_1000 != &addr_of_val_1001 (它们的引用不再相同)
但是,如果你加上,
b++;
或
b = Integer.valueOf(1001)
在你检查之前,它们将再次相等。