温故(2):pass by value
在Java领域中,这是一个被讨论得非常多的话题。可是,至今我发现还有很多人没有搞清楚(当然也包括本人)。直到看了这篇文章“Does Java pass by reference or pass by value? ”,才算完全明白。
从中,我发现一个很有趣的东西:图形比文字更能让人看懂、更直观。在上面那篇文章中,我想大家只要看看图(画的真棒)就可大致明白其中原理了。
为了便于理解,本人大致总结一下:
1、pass-by-reference和pass-by-value概念上有何不同?
推荐以下这篇文章“Reference 不为人知的一面”,从中摘取一段,解释的比较清楚:到底什么是pass by value?什么又是 pass by reference 呢?打个比方,pass by value 就是资料的「分身」传递过去,pass by reference 就是资料的「本尊」传递过去。
2、传递methods参数才会出现pass-by-reference/value的问题
大家都知道Java中所有对象变量都是reference,但这与我们所说的pass-by-reference/value没有什么关系。pass-by-reference/value只会在方法调用中才会出现,也就是说方法的参数是通过pass-by-reference还是pass-by-value进行传递。
3、Java中都是以pass-by-value的方式传递方法参数
Java中所有的参数都是采用pass-by-value进行传递,无论是Primitive type(int,short,float等),还是Objects。
4、区分可变对象(Mutable Objects)和不可变对象(Immutable Objects)
这两种对象很容易引起误会,看下面两个例子:
EX 1:
public class Test {
public static void test(String str) {
str = “World”; //1
}
public static void main(String[] args) {
String string = “Hello”;
test(string);
System.out.println(string);
}
}
运行结果:
Hello
—————————–
EX 2:
public class Test {
public static void test(StringBuffer str) {
str.append(“, World!”); //2
}
public static void main(String[] args) {
StringBuffer string = new StringBuffer(“Hello”);
test(string);
System.out.println(string);
}
}
运行结果:
Hello, World!
为什么一个能改变,而另一个不能改变呢?其实这就是不可变和可变对象引起的问题。根据第一篇文章你就应该很容易弄明白,String是不可变对象,在代码1处的str变量已经变成指向了另一个对象的reference(赋值语句相当于new),也就是说它只修改了另一个对象;而StringBuffer是可变对象,在代码2处它修改的是同一个对象。