码迷,mamicode.com
首页 > 其他好文 > 详细

通过引用传递字符串

时间:2015-01-09 22:29:34      阅读:242      评论:0      收藏:0      [点我收藏+]

标签: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是值传递的,所以x的值是指向”ab“的引用。当方法change()被调用时,它会创建一个新的对象”cd“。现在x指向”cd“,像下图这样:

技术分享
似乎是一个令人信服的解释。这完全符合Java总是通过值传递的结论。但是哪里出错了呢?

3.这段代码到底如何工作的


上面的解释有几处错误。为了更好的理解,我们简单介绍一下整个过程。
当字符串”ab“被创建的时候,Java分配了可以存储这个字符串大小的内存,这个字符串对象赋值给变量x,变量x实际上获得了指向这个对象的引用。这个引用是字符串对象存储在内存中的地址。
变量x包含指向这个字符串对象的引用。x本身并不是一个引用。它是存储一个引用的变量。
Java仅存在值传递。当x被传递给方法change()时,传递给这个方法的是x的一份拷贝。change()方法创建了另外一个对象cd,有一个不同引用指向它。变量x改变了指向字符串对象”cd“的引用,而不是引用本身。
下图向我们展示了事情的真相。
技术分享

4.错误的解释


上面的代码片段引出的问题与字符串的不可变性没有关系。即使用StringBuilder代替String,结果也是相同的。问题的关键是那个变量存储了引用,但它不是引用本身。

5.如何避免上面的问题


如果我们确实需要改变对象的值。首先,这个对象可以被改变,比如StringBuilder。第二,我们需要确保不会有新的对象被创建,然后赋给参数变量。因为Java是值传递的。
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");
}

通过引用传递字符串

标签:java   字符串   

原文地址:http://blog.csdn.net/u010133536/article/details/42559081

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!