java参数传递(一)江湖人称:java中是值传递方式而非引用传递,即所谓的:“传值”;那么在当参数是对象的时候不
java参数传递(一)
江湖人称:java中是值传递方式而非引用传递,即所谓的:“传值”;那么在当参数是对象的时候不是传递引用吗,java中对象的引用是指对象的地址,它也是一个整形值,即 “传址”,所以归根揭底java中的参数都是值传递
1,基本类型作为参数传递
请看实例代码:
public class RawType {public static void main(String[] args) {int i = 2000;int j = 5000;changInt(i,j);System.out.println(i+" "+j);}private static void changInt(int a, int b) {a = 1000;b = 8000;}}
打印结果: 2000 5000
分析:java中八种基本类型作为参数时,传递的都是基本类型的
值拷贝,即当调用方法changInt(int a, int b)时,在传递给方法的是i,j的一个内存拷贝,而并非真正的i,j自己,打印结果就是最好的证明.
这时在栈内存中开辟了临时的i,j的拷贝a,b,方法里面重新给拷贝赋值了,拷贝(a,b)自然是变了,但是i,j自己并没有因为方法调用而变化.
当方法调用结束时后,a,b自动销毁,因为在栈中其销毁不需要java虚拟机去回收的,自己销毁(表现出来的就是方法外a,b不能访问).

图 1-1
2,引用类型作为参数传递请看实例代码:
public class RawType {public static void main(String[] args) {String s1 = new String("abcString");StringBuffer s2 = new StringBuffer("abcBuffer");changString(s1);System.out.println(s1);changStringBuffer(s2);System.out.println(s2);}private static void changString(String a1) {a1 += ",ABCString";}private static void changStringBuffer(StringBuffer a2) {a2.append(",ABCBuffer");}}
打印结果:
abcString
abcBuffer,ABCBuffer
分析:可以看出String没有改变,而StringBuffer却改变了,有人说它不都是引用类型吗,为什么一个改变了一个却没有改变呢?
这个时候你就要注意java引用类型在内存中是如何分配的了,前面我们说过引用类型作为参数传递时传递的是对象的
地址拷贝(1) 当方法changString(String s1),changStringBuffer(StringBuffer s2)被调用之前内存中的地址分配如图所示,s1,s2是在栈中的两个地址,他们分别存储的是一个String和StringBuffer的对象引用.

图 2-1
(2) 当方法changString(String a1),changStringBuffer(StringBuffer a2)被调用的时候,内存中分别产生了s1,s2的一份地址拷贝a1,a2它们的指向自然是和s1,s2一样,内存中的地址分配如图所示,

图 2-2
(3) 当changString(String a1)中执行a1 += ",ABCString";操作时,据我们对String的了解,String一旦对象一旦创建就不可变(地址指向内容不可变,这里指abcString不可变);同时也由于java中String对"+"进行了重载,a1 += ",ABCString";事实上是相当于执行了a1 = new StringBuffer(s1).append(",ABCString")操作,可以看出是重新创建了一个新的对象,在新的对象里面存放的是abc,ABCString,也就是s1的地址拷贝此时有了新的地址(故指向的对象不一样了).
而changStringBuffer(StringBuffer a2)中执行a2.append(",ABCBuffer");时,并未产生新的对象,只是在原有对象的基础上追加",ABCBuffer",此时内存中的内存分配如图:

图 2-3
(4) 当两个方法调用都结束时,临时地址拷贝a1,a2都自动消失,那么此时的changString(String a1)中对象"abcString,ABCString”就没有了引用(表现出来的时候我们在程序中无法访问它了),因为对象本身是在堆中,故其会在某个时候被java虚拟机当成垃圾回收掉,它的内存空间重新归还给系统,此时内存分配情况如图所示:

图 2-4
(5) 从图图 2-4 和 图 2-3就可以看出为什么打印的结果是:
abcString
abcBuffer,ABCBuffer
综上所述:
java中引用类型当参数时候,传递的是实参的一份地址拷贝,但是实参和形参开始的指向是一样的,都是指向相同的对象,因为地址一样。那么当参数是数组的时候呢,而数组是基本类型或引用的时候又会怎么样呢?且听下回分解...