Java - 方法调用后对象状态不会更改

Ana*_*ige 11 java pass-by-reference pass-by-value

初学java问题,但我无法理解在下面的例子中,call-by-Value(或Reference)是如何工作的 -

为什么在我的自定义String对象退出方法后,String值不会被修改.?与Date等其他类相同

public class StringMadness {

public static void main(String[] args) {
    String s = "Native String";
    CustomStringObject cs = new CustomStringObject();
    System.out.println("Custom String Before: " + cs.str);
    hello(cs);
    System.out.println("Custom String After: " + cs.str);

    System.out.println("Native String Before: " + s);
    hello(s);
    System.out.println("Native String After: " + s);
}

private static void hello(String t) {
    t = "hello " + t;
}

private static void hello(CustomStringObject o) {
    o.str = "hello " + o.str;
  }
}

class CustomStringObject {

String str = "Custom String";
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 24

比较这两种方法:

private static void hello(String t) {
    t = "hello " + t;
}

private static void hello(CustomStringObject o) {
    o.str = "hello " + o.str;
}
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,您要为其分配新值t.这对调用代码没有任何影响 - 您只是更改参数的值,并且所有参数都在Java中通过值传递.

在第二种情况下,您要为其分配新值o.str.这正在改变对象o引用值的字段的值.调用者看到该更改,因为调用者仍然具有对该对象的引用.

简而言之:Java总是使用pass by value,但您需要记住,对于类,变量(或实际上任何其他表达式)的值是引用,而不是对象.您不需要使用参数传递来查看:

Foo foo1 = new Foo();
Foo foo2 = foo1;
foo1.someField = "changed";
System.out.println(foo2.someField) // "changed"
Run Code Online (Sandbox Code Playgroud)

这里的第二行复制了foo1into 的值foo2- 两个变量引用同一个对象,因此使用哪个变量访问它并不重要.