Java中参数传递问题


前段时间对Java中参数传递问题有点困惑,不了解其中的含义。查阅了很多资料,这里谈谈自己对该问题的理解。

参数传递一般有两种,一种是“传值”,另一种是“传地址值”。传值是指在调用方法时,把参数的值传递给方法,而传地址值则是给方法提供参数的地址值。Java中的参数传递方法都为传值调用。下面我通过例子来验证。

1.基本类型的参数传递      

 1 public class ParamTransfer {  2     public int money;  3     
 4     public void amethod(int i) {  5         System.out.println("方法得到的i的值:" + i);  6         i = i * 5;  7         System.out.println("方法执行语句i=i*5后i的值:" + i);  8         System.out.println("money的值:" + this.money);  9  } 10 
11     public static void main(String[] args) { 12         ParamTransfer pt = new ParamTransfer(); 13         pt.money = 100; 14  pt.amethod(pt.money); 15  } 16 
17 }
运行结果如下:
方法得到的i的值:100 方法执行语句i=i*5后i的值:500 money的值:100

注意对比形参i和money值的变化。这里我们把pt.money作为参数传递给amethod方法,该方法中i得到的值是100,这个我们从运行结果中可知。执行完i=i*5语句后我们发现当前对象的money属性值并没有发生改变,这就说明这里只是传了一个100数值给形参i,相当于把pt.money的值拷贝给i,i的变化并不会影响pt.money的值,仅仅是传数值。

2.引用类型的参数传递

 1 class Time {  2     public int hour;  3     public int minute;  4     public int second;  5 }  6 
 7 public class ObjectParamTransfer {  8  Time time;  9 
10     public static void main(String[] args) { 11         ObjectParamTransfer opt = new ObjectParamTransfer(); 12         opt.time = new Time(); 13         opt.time.hour = 11; 14         opt.time.minute = 22; 15         opt.time.second = 33; 16 
17         System.out.println("time的属性值:"); 18         System.out.println("hour=" + opt.time.hour); 19         System.out.println("minute=" + opt.time.minute); 20         System.out.println("second=" + opt.time.second); 21 
22         opt.method(opt.time);//将对象引用作为参数传递给方法method 23         //对比执行方法后的变化
24         System.out.println("执行方法后的time的属性值"); 25         System.out.println("hour=" + opt.time.hour); 26         System.out.println("minute=" + opt.time.minute); 27         System.out.println("second=" + opt.time.second); 28 
29  } 30 
31     private void method(Time t) { 32         System.out.println("参数t的属性值:"); 33         System.out.println("hour=" + t.hour); 34         System.out.println("minute=" + t.minute); 35         System.out.println("second=" + t.second); 36         System.out.println("对t和time进行==比较,结果为:" + (t == this.time)); 37 
38         System.out.println("改变t的实例变量值"); 39         t.hour = 44; 40         t.minute = 55; 41         t.second = 60; 42  } 43 }
运行结果如下:
time的属性值: hour
=11 minute=22 second=33 参数t的属性值: hour=11 minute=22 second=33 对t和time进行==比较,结果为:true 改变t的实例变量值 执行方法后的time的属性值: hour=44 minute=55 second=60

将对象引用opt.time传递给method方法后先输出参数t的属性值,发现和原来对象引用的属性值是相同的。进一步返回t==this.time的结果为true。改变t的实例变量值后,当前引用opt.time的属性值也随之发生改变。这就充分证明了参数t和对象引用opt.time指向同一对象,即它们指向的内存空间地址一致。那么问题来了,到底是opt.time这个引用传递了内存空间地址值给参数t还是它自己就是这个参数t呢?这我们不得而知。下面再通过一个例子来证明。

 1 public class ObjectParamTransfer2 {  2  Time time1;  3  Time time2;  4 
 5     public static void main(String[] args) {  6         ObjectParamTransfer2 opt = new ObjectParamTransfer2();  7         opt.time1 = new Time();  8         opt.time2 = new Time();  9         opt.time1.hour = 12; 10         opt.time2.hour = 23; 11         System.out.println("交换前的值:"); 12         System.out.println("time1.hour=" + opt.time1.hour); 13         System.out.println("time2.hour=" + opt.time2.hour); 14 
15  opt.swap(opt.time1, opt.time2); 16         System.out.println("交换后的值:"); 17         System.out.println("time1.hour=" + opt.time1.hour); 18         System.out.println("time2.hour=" + opt.time2.hour); 19  } 20 
21     private void swap(Time t1, Time t2) { 22  Time temp; 23         temp = t1; 24         t1 = t2; 25         t2 = temp; 26  } 27 
28 }
运行结果如下:
交换前的值: time1.hour
=12 time2.hour=23 交换后的值: time1.hour=12 time2.hour=23

这里写了一个交换两个引用的swap的方法。但是我们从结果中发现调用该方法后输出结果并没有发生改变。说明该方法并没有对opt.time1和opt.time2这两个引用进行交换。在该方法中只是对参数t1,t2进行交换,验证了上个例子中引用传递的是内存空间地址值,并非参数就是该引用(即传的不是引用)。对参数的操作并不会影响原来的引用,只会影响参数和引用所指的同一个内存空间里面的内容。这就证明了引用类型参数传递并不是传引用,而只是传该引用的内存地址值。

3.参数传递中的一种特殊情况

在上面的例子中我们已经知道了基本类型的参数传递传的是传数值,引用类型的参数传递传的是内存地址值。但我在学习过程中碰到一种特殊情况:

 1 public class Test {  2     public static void main(String[] args) {  3         String str = new String("abc");  4  change1(str);  5  System.out.println(str);  6  }  7     
 8     private static void change1(String str1) {  9         str1 += "123"; 10  System.out.println(str1); 11  } 12 }
运行结果:
abc123 abc

按上面得出的结论来看,引用类型的参数传递传递的是内存地址值,str和str1指向的是同一个内存空间,str1将内存空间里面的内容改变后输出str也应该发生改变。但是str指向的内存空间里的内容“abc”并没有发生变化。这里我理解为String类型的引用传递传的是内容,并不是内存空间地址值。(与第一个例子中传数值类似)并不会影响原来引用所指的内存空间的内容。可能这也是String对象内容不可变的原因?

因为目前还在基础阶段,学习的还不够深刻自己也有点疑问,以上理解可能存在偏差和错误,如有错误请大家指出。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM