Java自学笔记系列七:封装(三) Java传值调用之我见

  先看下面的一段代码:

  
  
  
  
  1. package com.ivantian.CoreFengZhuang; 
  2.  
  3. //call by values 
  4. //call by address 
  5. public class Difference { 
  6.  
  7.     int x = 10// 成员变量 
  8.      
  9.     public static void main(String[] args) { 
  10.          
  11.         int  a = 10
  12.         int  b = a; 
  13.         System.out.println("这是传值引用:"); 
  14.         System.out.println("测试前的数据:"); 
  15.         System.out.println("a的数值是:" + a + " b的数值是:" + b); 
  16.         a = 20
  17.         System.out.println("测试后的数据:"); 
  18.         System.out.println("a的数值是:" + a + " b的数值是:" + b); 
  19.          
  20.         System.out.println(); 
  21.          
  22.         System.out.println("这是传地址引用:"); 
  23.         Difference diff = new Difference(); 
  24.         Difference diff1 = diff; // 让 diff拥有同样的参考
  25.         System.out.println("测试前的数据:"); 
  26.         System.out.println("diff.x = " + diff.x +" diff1.x = " + diff1.x); 
  27.         diff.x = 100
  28.         System.out.println("测试后的数据:"); 
  29.         System.out.println("diff.x = " + diff.x +" diff1.x = " + diff1.x); 
  30.     } 
  31. //执行结果如下 
  32. /* 
  33. 这是传值引用: 
  34. 测试前的数据: 
  35. a的数值是:10 b的数值是:10 
  36. 测试后的数据: 
  37. a的数值是:20 b的数值是:10 
  38.  
  39. 这是传地址引用: 
  40. 测试前的数据: 
  41. diff.x = 10 diff1.x = 10 
  42. 测试后的数据: 
  43. diff.x = 100 diff1.x = 100 
  44.  
  45. */ 

  不错,是和C/C++的一些程序示例是相似的,实际上,在C++中有两种传递参数的方式:传值调用(call by alues) 和 传参考调用(call by reference)的方式,而在Java中只有传值调用你不仅会好奇的问,上面的例子中diff不是传递的“参考”吗?

  对的,此"参考"是Java世界中的参考,与C++中的参考还有所不同。在前面的几篇文章,比如数组,字符串章节都有“参考”一词的出现,若有疑问请及时联系,并可以参考前面的文章。

 对上面程序例子的解释如下:

    传值引用主要是针对基本数据类型而言。所谓传值引用就是再进行变量的传递过程中,传递的是变量的实际的值,就是实际值的复制。由于一个变量值不会影响另一个变量值的改变,所以操作后的结果不会影响原来的值。


    传地址引用主要是针对对象操作,他传递的是一个对象句柄的复制。也就是形成了多个变量操作一个对象的局面,任何一个针对句柄操作的变量,都会影响到其他的变量。

   因此我认为:

    "在java世界中只存在一种传值调用(Call by value)。其实上面的两种方式传递的都是“值”,对于对象而言只不过传过去的值只是一个对象的地址值,只是所反映出来的现象和"传引用调用"相似罢了,但实质是传值调用。而在C++中,还存在一种传参考调用或者叫做传引用调用(Call by Reference)。"

 很多初学者对着两个概念容易混淆。其实笔者也是一样。再看下面的一个程序示例:

 还以FindWife为例子。

 先上代码:

  
  
  
  
  1. package com.ivantian.CoreFengZhuang; 
  2.  
  3. // Object's calling by value(s) 
  4.  
  5. // Class Definitions 
  6. class Wives{ 
  7.     String name; 
  8.     Wives(String name){ 
  9.         this.name = name; 
  10.     } 
  11.      
  12.  
  13. //Testing ,Finding wives   
  14.  
  15. public class FindWives { 
  16.  
  17.   //FengJie 之归我所有 很难驾驭 
  18.   public static void FengJie(Wives w){ 
  19.       w.name = "FengJie"
  20.   } 
  21.   //FuRong 之归我所有 乖巧懂事 
  22.   public static void FuRong(Wives w){ 
  23.       w = new Wives("FuRong"); 
  24.   } 
  25.    
  26.   //main method   
  27.   public static void main(String[] args) { 
  28.      
  29.      //把 FengJie换成 白娘子 
  30.      Wives wife = new Wives("白娘子"); 
  31.      FindWives.FengJie(wife); //能够 更换成功吗? 
  32.      System.out.println("My wife will be :" + wife.name); 
  33.       
  34.      //把 FuRong 换成 白娘子 
  35.      Wives wife1 = new Wives("白娘子"); 
  36.      FindWives.FuRong(wife1);//  
  37.      System.out.println("My wife will be :" + wife1.name); 
  38.      

  执行结果呢?这里先买个关子,下面逐步来分析。

  眼下有三大奇女子“FengJie,FuRong,白娘子”供我选择,若是用纳什均衡理论,可以很快作出“最优解”的判断,但是我们不是做经济学研究的。

  方案一:

   事实上,还是找“白娘子”这样的wife比较不错,白富美,还能上天入地。先让她和FengJie做个比较。FengJie利用她自身的"技能Fengjie()"迫使白娘子wife同意Fengjie w 来参考她的名字,FengJie w 当然高兴了。如图一所示:

图一:wife与w参考同一对象

 FengJie()说,我的名字是:FengJie,不容改变。于是白娘子也奈何不了她。如图二:

图二 :将w参考的对象的name指定为:FengJie

  在主程序执行完FengJie()后,FengJie()中的对象w就被法海(JVM)给“垃圾回收(GC)”了,输出要取得wife.name并显示出来。其实最后得到的是”白娘子“的对象,但她用的是”FengJie“的名字。不过这样也好,JVM没有机会镇她了.FengJie是江湖没有此人,却流传此人的传说。

  FuRong也打算同样的想法来对付白娘子,操作如图三所示: 

        图三:wife1与参数w参考同一对象

因为FuRong目睹了FengJie的悲惨结局,她自己留了一手,在FuRong()中建立了一个系对象w,并指定给w参考,如图四,

图四:w参考之新建的对象

在主程序执行完FuRong()后,FuRong()中的新建的对象w就被法海(JVM)给“垃圾回收(GC)”了,输出要取得wife1.name并显示出来。其实最后得到的是”白娘子“的对象,也是她自己的名字“白娘子”。可惜FuRong,江湖不再有FuRong的任何传说。

  所示,程序执行的结果是:

  
  
  
  
  1. /*程序执行的结果 
  2. My wife will be :FengJie 
  3. My wife will be :白娘子 
  4. */ 

  以上就是我对:Java"传值调用"的看法了,欢迎指正!

你可能感兴趣的:(java,参考,传值调用)