为什么不更新对象

时间:2019-03-27 04:44:58

标签: java wrapper autoboxing

我已经编写了这段代码,我想知道为什么所引用的对象的值没有被更改

java中的所有调用都是按值调用。但是当调用指向同一个对象时,为什么不更新对象

class Main {
  public static void main(String[] args) {
    Integer n = 3;
    triple(n);
    System.out.println("Hello world! " + n);
  }
  public static void triple(Integer x)
  {
    x *= 8;
    System.out.println("Hello world! " + x);
  }
}

实际输出

Hello world! 24
Hello world! 3

但是我认为输出应该是

Hello world! 24
Hello world! 24

之所以这样,是因为对Integer类进行了拆箱和自动装箱,所以创建了一个与“ x”同名的新对象,因为Integer是不可变的,它在本地可用,并且不指向参数/对象正在通过-n。

1 个答案:

答案 0 :(得分:1)

Integer n传递给triple方法时,实际上是在传递Integer对象n的引用值。

因此,在triple方法中,另一个局部变量x在被调用时指向该参考值。在方法内部,当此Integer对象的值乘以8时,它将创建Integer的另一个 new 实例,因为Integer immutable < / em>本地变量x指向的位置。

因此您不会在打印语句System.out.println("Hello world! " + n);中看到此新值,因为n仍指向Integer的旧实例,该实例仍为3

如果您使用StringBuilder尝试此操作,则会得到您期望的结果:

public static void main(String[] args) {
    StringBuilder n = new StringBuilder("foo");
    triple(n);
    System.out.println("Hello world! " + n);
}

public static void triple(StringBuilder s) {
    s.append("bar");
    System.out.println("Hello world! " + s);
}

这里的输出将是:

Hello world! foobar
Hello world! foobar

这是因为StringBuilder可变的,如果triple通过附加数据来修改数据,则原始指针n和新指针{ {1}}将指向对象引用的相同值。