您的位置:首页 > 编程语言 > Java开发

Java String对象以“引用”方式被传递

2013-11-30 10:18 381 查看
译文路径:String is passed by “reference”in
Java

Java String对象以“引用”方式被传递

这是Java的一个经典问题。很多类似的问题已经在StackOverflow被问,这里面有很多的不正确/不完整的答案。这个问题很简单,如果你不去想太多。但如果你更深入地思考,它可能是非常令人困惑的。



1、一个段有趣和令人困惑的代码

public static void main(String[] args) {
String x = new String("ab");
change(x);
System.out.println(x);
}

public static void change(String x) {
x = "cd";
}

打印结果:ab

在C++中,代码如下

void change(string &x) {
x = "cd";
}

int main(){
string x = "ab";
change(x);
cout << x << endl;
}

打印结果:cd

 

2、常见的困惑问题

x存储指向堆中的“ab”字符串的引用。所以,当x被作为参数传递到change()方法时,它仍然指向堆中“ab”,像下面这样:



 

因为java是按值传递的(pass-by-value), x的值是“ab”的引用。当方法的change()被调用,它会创建一个新的“cd”的对象,而x现在是指向“cd”像下面这样:



 

这似乎是一个相当合理的解释。他们明确表示,Java是总是传递按值。但是,错在哪里呢?



3、代码真正做了些什么呢?

上面的解释有几个错误。为了容易理解这一点,这是一个好主意,简单地描述整个过程。

当字符串“ab”被创建,java分配存储字符串对象所需的内存空间。然后,将对象分配给变量x,该变量是被实际分配的引用对象。此引用是该对象被存储在内存的地址。

变量x包含一个字符串对象的引用。 x不是引用本身!它是用于存储一个引用(内存地址)的变量。

Java是仅仅是按值传递。当x传递给change()方法,x的(引用)值的副本被传递。方法change()创建另一个对象“cd”,它有一个不同的引用。它是被改变的x副本指向“cd”的变量,而不是x引用本身。

下面的图表展现了真实的过程:




 

4、错误的解释

从第一个代码片段中所提出的问题是没有联系到String对象的不变性。即使字符串被替换StringBuilder的,结果还是一样。关键的一点是,变量存储的是引用,而不是引用本身!

5、这个问题的解决方法

如果我们真的需要改变对象的值。首先,对象应该是可变的,例如,StringBuilder对象。其次,我们需要确保没有创建新的对象并将此对象分配给参数变量,因为Java是只是按值传递(passing-by-value)。

public static void main(String[] args) {
StringBuilder x = new StringBuilder("ab");
change(x);
System.out.println(x);
}

public static void change(StringBuilder x) {
x.delete(0, 2).append("cd");
}

Related posts:

Yet
Another “Java Passes By Reference or By Value”?
Notes
from “Sun Certified Programmer for Java 6 Study Guide”
Diagram
to show Java String’s Immutability
Overriding
and overloading in Java with examples



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐