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.这段代码到底做了什么? 上面的解释有几处错误。为了更容易理解,通过我们最好简单的引用过一下整个流程。 当字符串"cd" 被创建时,网站模板传递java会分配储存字符串所需要的内存量。然后,对象被分配给了变量x,实际上是将对象的引用分配给了变量x。这个引用是对象储存的内存地址。 变量x包含了一个指向字符串对象的引用,x并不是字符串对象本身。它是一个储存了字符串对象ab引用的变量。 java是按值传递的。当x被传递给change()方法时,实际上是x的值(一个引用)的一个副本。方法change被调用后,会创建另一个对象"cd",它有着一个不同的引用。方法内的局部变量x的值变成了"cd"的引用。这里改变的源码库是方法内的局部变量的引用值,而不是改不了原先引用的字符串"ab"。 看图: 4.错误的解释: 从第一个代码片段引发的问题与字符串不可变性没有任何关系。即使String被StringBuilder替换,结果仍然是一样的。关键点是变量存储的是对象引用,而不是对象本身! 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"); } http://shenzhen.offcn.com/