这个问题已经在这里有一个答案:
- 就是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";
}
比较这两种方法:
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"
这里的第二行拷贝的价值foo1
到foo2
-这两个变量指向同一个对象,因此它并不重要,你可以访问它的变数。
有两种方法之间的一个重要区别:使用hello(String)
你试图改变参考 String
,并与hello(CustomObject)
给定一个参考,你使用的参考来改变对象的成员。
hello(String)
采用对一个参考String
。 在功能你想改变哪个对象是参考点,但你只改变基准的通按值拷贝 。 所以,你的变化是不是方法外部的反射。
hello(CustomObject)
被赋予一个引用的副本到一个对象,然后可以用它来改变实际的对象。 这个作为改变对象的内容 。 所以,你的变化反映在调用者。
给一个对象的引用 ,您可以使用它公开的方法/域更改对象
t
将指向新的对象和作用范围的方法而已,所以外界的变化不可见。
第二种情况,要更改值将被更新为对象,所以这些变化的方法调用后可见。