java参数传递(到底是值传递还是引用传递?)
结论
1、基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的
2、对象作为参数传递时,是把对象在内存中的地址拷贝了一份传给了参数。
Java中的参数传递机制一直以来大家都争论不休,究竟是“传值”还是“传址(传引用)”,争论的双方各执一词,互不相让。不但“菜鸟”们一头雾水,一些“老鸟”也只知道结果却说不出所以然来。我相信看过下面的内容后,你就会明白一些。
先看基本类型作为参数传递的例子:
public class Test1 {
public static void main(String[] args) {
int n = 3;
System.out.println("Before change, n = " + n);
changeData(n);
System.out.println("After changeData(n), n = " + n);
}
public static void changeData(int nn) {
n = 10;
}
}
我想这个例子大家都明白,基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的,输出的结果证明了这一点:
Before change, n = 3
After changeData(n), n = 3
那么,我们现在来看看对象作为参数传递的例子,这也是大家争论的地方。
public class Test2 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello ");
System.out.println("Before change, sb = " + sb);
changeData(sb);
System.out.println("After changeData(n), sb = " + sb);
}
public static void changeData(StringBuffer strBuf) {
strBuf.append("World!");
}
}
先看输出结果:
Before change, sb = Hello
After changeData(n), sb = Hello World!
从结果来看,sb的值被改变了,那么是不是可以说:对象作为参数传递时,是把对象的引用传递过去,如果引用在方法内被改变了,那么原对象也跟着改变。从上面例子的输出结果来看,这样解释是合理。
现在我们对上面的例子稍加改动一下:
public class Test3 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello ");
System.out.println("Before change, sb = " + sb);
changeData(sb);
System.out.println("After changeData(n), sb = " + sb);
}
public static void changeData(StringBuffer strBuf) {
strBuf = new StringBuffer("Hi ");
strBuf.append("World!");
}
}
按照上面例子的经验:对象作为参数传递时,是把对象的引用传递过去,如果引用在方法内被改变了,那么原对象也跟着改变。你会认为应该输出:
Before change, sb = Hello
After changeData(n), sb = Hi World!
但运行一下这个程序,你会发现结果是这样的:
Before change, sb = Hello
After changeData(n), sb = Hello
这是因为Text3 new一个新的对象后strBuf指向了新的对象,对新的对象操作当然不会改变原对象啦~
String类是个特殊的类,对它的一些操作符是重载的,如:
String str = “Hello”; 等价于String str = new String(“Hello”);
String str = “Hello”;
str = str + “ world!”;等价于str = new String((new StringBuffer(str)).append(“ world!”));
因此,你只要按上面的方法去分析,就会发现String对象和基本类型一样,一般情况下作为参数传递,在方法内改变了值,而原对象是不会被改变的。