简体   繁体   English

为什么值不更新?

[英]Why isn't the value updated?

It is a very basic question, but I don't seem to understand why this doesn't work. 这是一个非常基本的问题,但我似乎不明白为什么这不起作用。 As far as I know, a and b would be pointers (in C thinking) to Integer objects. 据我所知, ab将成为Integer对象的指针(在C思考中)。 Why is the output 3 2 and not 3 3 ? 为什么输出3 2而不是3 3 I would have expected the value of b to also be incremented when incrementing a. 我希望在递增a时,b的值也会增加。

Integer a = new Integer(1);
Integer b = new Integer(2);
a = b;
a++;
System.out.print(a + " " + b);

The keyword here is auto-boxing 这里的关键字是自动装箱

https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

Basically, the java compiler automatically converts between the Integer class and the primitive type int in the "appropriate" context. 基本上,java编译器在“适当”上下文中自动在Integer类和基本类型int之间进行转换。 One such context is assignment. 一个这样的背景是分配。

Integer is immutable, and a++ , like a = a + 1 , sets a to refer to a different immutable object. Integer是不可变的,而a++ ,如a = a + 1 ,设置a来引用不同的不可变对象。

In other words: a = b sets a to refer to the same object as b , but after a++ , a and b refer to different objects again. 换句话说: a = b设置a引用与b相同的对象,但在a++ab再次引用不同的对象。

It is not equivalent to the C code that I suspect you're thinking of; 等同于我怀疑你想到的C代码;

int *a = malloc(sizeof(*a));
*a = 1;
int *b = malloc(sizeof(*b));
*b = 2;
a = b;
(*a)++;

Thinking about Java references in terms of C pointers, or C++ references, easily leads the mind astray. 从C指针或C ++引用的角度思考Java引用很容易导致思维误入歧途。

Firstly, in case of java, the term used is an object 'reference' and not a 'pointer'. 首先,在java的情况下,使用的术语是对象'reference'而不是'pointer'。 Basically it means that its a logical reference to the actual object. 基本上它意味着它是对实际对象的逻辑引用。

Further more as already noted by Lagerbaer, its autoboxing-unboxing that is transparent which effectively increments the value, creates a new object and then assigns it back to the reference. 正如Lagerbaer已经指出的那样,它的自动装箱 - 拆箱是透明的,可以有效地增加值,创建一个新对象,然后将其分配回参考。

So at the end of the increment operation, there are two objects instead of one. 所以在增量操作结束时,有两个对象而不是一个。

The increment operation after unboxing would probably look something like this : 取消装箱后的增量操作可能如下所示:

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

Integer是一个不可变类型,因此您无法更改方法中的值。

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

Before the a++ instruction you have: a++指令之前你有:

      +---------+
a --->| Integer |
b --->|    2    |
      +---------+

Both a and b pointing at the same Integer object with value 2. ab指向具有值2的相同Integer对象。

With the a++ instruction, Java autoboxing does these steps automatically for you: 使用a++指令,Java autoboxing会自动为您执行以下步骤:

  1. Convert the Integer with value 2 to a primitive type int with value 2. 将值为2的Integer转换为值为2的基本类型int
  2. Increment the primitive value int to 3. 将原始值int增加到3。
  3. Convert the primitive type int with value 3 to an Integer with value 3, which will give you a new instance. 将具有值3的基本类型int转换为值为3的Integer ,这将为您提供一个新实例。 As other pointed out, Integer is an immutable class, so you get different objects for different values. 正如其他人所指出的, Integer是一个不可变类,因此您可以为不同的值获取不同的对象。

So you end up with: 所以你最终得到:

      +---------+         +---------+
a --->| Integer |   b --->| Integer |
      |    2    |         |    3    |
      +---------+         +---------+

你正在递增a的值,这对a的值没有任何影响,因为ba无关。

As Sean already answered, Integer (just like String) is immutable, that means it's value can't be changed. 正如肖恩已经回答的那样,Integer(就像String一样)是不可变的,这意味着它的价值无法改变。 So your call to a++ actually created a new Integer with value a+1 and stored that as a . 所以你要调用a++实际上创造了一个新的整数与值+ 1和存储作为a Meanwhile b is still pointing at the old Integer. 同时b仍然指着旧的整数。

This can be shown by comparing the References ( == operator). 这可以通过比较References( ==运算符)来显示。 Before a++ a==b returns true (same reference/object). a++ a==b之前返回true (相同的引用/对象)。 After a++ a==b returns false , as a is now pointing at a new Integer object. a++ a==b返回false ,作为a正在指向一个新的Integer对象。

Why do you think b should be 3? 为什么你认为b应该是3? You never change that value! 你永远不会改变这个价值!

Integer a = new Integer(1);     // a is 1
Integer b = new Integer(2);     // b is 2
a = b;                          // a now is 2
a++;                            // a now is 3
System.out.print(a + " " + b);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM