在C中 函数参数的传递方式称为单向的“值传递”
而在Java中,虽然没有具体说明是什么传递方式,但是可以从底层的数据存储角度考虑:
Java的基本变量存在于 Java虚拟机的栈中,而对象 ,引用变量 则是把 其地址放在栈中,对应的值存在堆中。
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
但是如果使用一个jdk自带的引用类型StringBuffer
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!");
}
那么产生则会类似C++的地址传递的效果。
输出结果:
Before change, sb = Hello
After changeData(n), sb = Hello World!
其原理就是使新产生的strBuf指向了原来内存单元中的sb所指的的位置,append便实现了对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 = Hello
方法开始的时候直接让strbuf指向了一个新的内存空间,内容为“Hi”
有人可能会觉得是“Hi world”
没错,确实strbuf 的内容应该是“Hi world”,但是主函数中输出的是sb的内容,和strbuf早就没有关系了
要注意通过new StringBuffer使得strbuf 已经不是原来拷贝的那个sb的地址了