爪哇 - 对象状态的方法调用之后不改变[复制](Java - Object state does n

2019-06-26 17:49发布

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

  • 就是Java“传递通过引用”或“传递的价值”? 79个回答

初学Java的问题,但我不明白怎么称呼按值(或参考)是工作在下面的例子中 -

为什么它退出方法后,而我的自定义String对象的字符串值不被修改。 ? 同样的,其他类,如日期..

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";
}

Answer 1:

比较这两种方法:

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

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

在第一种情况下,你分配一个新值t 。 这将调用代码没有任何影响 - 你只是改变参数的值,并且所有的参数都是由Java的值传递。

在第二种情况下,你要指定一个新值o.str 。 这是改变这种价值的对象中的一个字段的值o指。 来电者看到变化,因为调用者仍然对该对象的引用。

总之:Java的总是值使用通,但你必须记住,类变量(或任何其他表达式)的值是一个参考,而不是一个对象。 你不需要使用参数传递给看到这一点:

Foo foo1 = new Foo();
Foo foo2 = foo1;
foo1.someField = "changed";
System.out.println(foo2.someField) // "changed"

这里的第二行拷贝的价值foo1foo2 -这两个变量指向同一个对象,因此它并不重要,你可以访问它的变数。



Answer 2:

有两种方法之间的一个重要区别:使用hello(String)你试图改变参考 String ,并与hello(CustomObject)给定一个参考,你使用的参考来改变对象的成员。

hello(String)采用对一个参考String 。 在功能你想改变哪个对象是参考点,但你只改变基准的通按值拷贝 。 所以,你的变化是不是方法外部的反射。

hello(CustomObject)被赋予一个引用的副本到一个对象,然后可以用它来改变实际的对象。 这个作为改变对象的内容 。 所以,你的变化反映在调用者。

给一个对象的引用 ,您可以使用它公开的方法/域更改对象



Answer 3:

因为对于字符串你只是改变局部参数参考。



Answer 4:

t将指向新的对象和作用范围的方法而已,所以外界的变化不可见。

第二种情况,要更改值将被更新为对象,所以这些变化的方法调用后可见。



Answer 5:

不工作,因为字符串是不可变对象



文章来源: Java - Object state does not change after method call [duplicate]