为什么对象没有更新[重复]

问题描述 投票:0回答:1

这个问题在这里已有答案:

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

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是不可变的,在本地可用,并且不指向参数/传递的对象 - ñ。

java wrapper autoboxing
1个回答
1
投票

当你将Integer n传递给triple方法时,你实际上传递了Integer对象n的引用值。

所以在triple方法中,另一个局部变量x在被调用时指向该引用值。在方法内部,当它将此Integer对象的值与8相乘时,它将创建另一个Integer的新实例,因为Integer是不可变的,局部变量x将指向该实例。

所以你不会在print语句System.out.println("Hello world! " + n);中看到这个新值,因为n仍然指向仍然是3的Integer的旧实例。

如果你用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和新指针s将指向对象引用的相同值。

© www.soinside.com 2019 - 2024. All rights reserved.