java中string索引传递
这是非常基础的的java问题。很多相同的问题在stackoverflow都被问,同时有很多不正确或者未完成的回答。这个问题很简单,但是你不好好想想,你会感到疑惑,使用你最好好好想想。
1.代码片段很有趣同时也会让人疑惑
|
|
这将会输出ab
。
在C++中,这代码如下:
|
|
但是输出是cd
。
2. 常见疑惑的问题
在堆中x存储的索引是指向字符串”ab”的。所以当x以参数传递给change()方法,在堆中它仍然指向”ab”,如下图:
因为,在java是通过值进行传递的,x的值指向”ab”。当 change()调用的时候,将会创建”cd”对象,同时x指向了”cd”。如图:
这看起来似乎是一个很合理的解释。java都是使用值传递,但是这错在哪了?
3. 这代码实际做什么?
上面的解释有几个错误。为了更加好明白,我们来简单走走这个过程。
当”ab”创建时候,java花费时间申请内存来储存对象。然后这个对象被赋予了x变量,这个变量就实际指向了这个对象。这个索引是存储这个对象内存的地址。
x变量包含了一个string对象的索引。x并没有自己的索引。它只是一个存储索引的变量(内存地址)。
java是只通过值传递的。所以当x通过change()传递的时候,拷贝了x的值(一个索引)来传递。在change()方法中创建了另外一个对象”cd”并且它有不同的索引。这时是变量x改变了它的索引(b变成了”cd”),而不是索引自身。
过程可以用下图表示:
4. 错误的解释
这个问题来源于他的第一行代码使用了不可变的string。即使String换成StringBuilder,借输出结果还是一样的。最关键的是变量存储了索引,但是它没有索引自己。
5. 解决这个问题
如果我们确实需要改变对象的值,首先对象是可变的,比如: StringBuilder,其次我们需要确保没有新创建对象赋予传递参数,因为java本来就是通过值传递的。
|
|