这个问题大家肯定碰到了很多了。今天来讲点原理性的,方便大家的理解。
首先来看个例子:
最常见的问题是结果怎么是javajavac呢??很多人把这个原因归结为call by value还是call by reference的问题,其实并非如此。
首先java对象都是建立在heap上的,对java对象的传递规定使用call by reference,所以String和StringBuffer都是call by reference,可以参考《thinking in java》,这是完全没有争议的。因此StringBuffer输出了call by reference的正确值javac;但同时看到String却没有输出lava,因此你可能会误认为String是call by value的,这是一个概念性的错误。String是一个特殊的类,特殊在它用了final关键字修饰,也就是说每个String都是不变的 (immutable)。你可能会问像s = s + "abc";这样的语句String变了。那么,分析下这句话就知道了,虚拟机新分配一段空间,将s这个引用指向的字符串和另一个字符串abc拿出来拼在 一起装在这个空间中,之后将s指向这个空间,所以String实际上没变,注意到第一个String是s的老空间,第二个String是"abc",第三 个字符串是s + "abc",它们三个的地址都不同。
回过头来解决上面这个问题。当String被传进stringReplace()后多了一个引用text指向原引用textString,这时我们对 text进行操作text = text.replace("j","l");当执行完后新分配了一个存储空间放"lava",text指向这个存储空间,但接下来函数执行完返回。可以 想像结果,因为String的特殊性,text并没有操作了原来那个字符串(textString指向的那个),而是在一个新的地址,所以原来那个 textString仍然不变,输出自然也不会变。
如果要得到改变了的值,那么就需要把地址传回来,具体代码如下:
呵呵,就写到这里吧,希望通过这么一讲能够让我们少犯点错误。