当前位置:编程学习 > JAVA >>

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

  先看下面的一段代码:
package com.ivantian.CoreFengZhuang; 
 
//call by values 
//call by address 
public class Difference { 
 
    int x = 10; // 成员变量 
     
    public static void main(String[] args) { 
         
        int  a = 10; 
        int  b = a; 
        System.out.println("这是传值引用:"); 
        System.out.println("测试前的数据:"); 
        System.out.println("a的数值是:" + a + " b的数值是:" + b); 
        a = 20; 
        System.out.println("测试后的数据:"); 
        System.out.println("a的数值是:" + a + " b的数值是:" + b); 
         
        System.out.println(); 
         
        System.out.println("这是传地址引用:"); 
        Difference diff = new Difference(); 
        Difference diff1 = diff; // 让 diff拥有同样的参考
        System.out.println("测试前的数据:"); 
        System.out.println("diff.x = " + diff.x +" diff1.x = " + diff1.x); 
        diff.x = 100; 
        System.out.println("测试后的数据:"); 
        System.out.println("diff.x = " + diff.x +" diff1.x = " + diff1.x); 
    } 
//执行结果如下 
/* 
这是传值引用: 
测试前的数据: 
a的数值是:10 b的数值是:10 
测试后的数据: 
a的数值是:20 b的数值是:10 
 
这是传地址引用: 
测试前的数据: 
diff.x = 10 diff1.x = 10 
测试后的数据: 
diff.x = 100 diff1.x = 100 
 
*/ 
 
  不错,是和C/C++的一些程序示例是相似的,实际上,在C++中有两种传递参数的方式:传值调用(call by alues) 和 传参考调用(call by reference)的方式,而在Java中只有传值调用。你不仅会好奇的问,上面的例子中diff不是传递的“参考”吗?www.zzzyk.com
  对的,此"参考"是Java世界中的参考,与C++中的参考还有所不同。在前面的几篇文章,比如数组,字符串章节都有“参考”一词的出现,若有疑问请及时联系,并可以参考前面的文章。
 对上面程序例子的解释如下:
    传值引用主要是针对基本数据类型而言。所谓传值引用就是再进行变量的传递过程中,传递的是变量的实际的值,就是实际值的复制。由于一个变量值不会影响另一个变量值的改变,所以操作后的结果不会影响原来的值。
 
    传地址引用主要是针对对象操作,他传递的是一个对象句柄的复制。也就是形成了多个变量操作一个对象的局面,任何一个针对句柄操作的变量,都会影响到其他的变量。
   因此我认为:
    "在java世界中只存在一种传值调用(Call by value)。其实上面的两种方式传递的都是“值”,对于对象而言只不过传过去的值只是一个对象的地址值,只是所反映出来的现象和"传引用调用"相似罢了,但实质是传值调用。而在C++中,还存在一种传参考调用或者叫做传引用调用(Call by Reference)。"
 很多初学者对着两个概念容易混淆。其实笔者也是一样。再看下面的一个程序示例:
 还以FindWife为例子。
 先上代码:
package com.ivantian.CoreFengZhuang; 
 
// Object's calling by value(s) 
 
// Class Definitions 
class Wives{ 
    String name; 
    Wives(String name){ 
        this.name = name; 
    } 
     
 
//Testing ,Finding wives   
 
public class FindWives { 
 
  //FengJie 之归我所有 很难驾驭 
  public static void FengJie(Wives w){ 
      w.name = "FengJie"; 
  } 
  //FuRong 之归我所有 乖巧懂事 
  public static void FuRong(Wives w){ 
      w = new Wives("FuRong"); 
  } 
   
  //main method   
  public static void main(String[] args) { 
     
     //把 FengJie换成 白娘子 
     Wives wife = new Wives("白娘子"); 
     FindWives.FengJie(wife); //能够 更换成功吗? 
     System.out.println("My wife will be :" + wife.name); 
      
     //把 FuRong 换成 白娘子 
     Wives wife1 = new Wives("白娘子"); 
     FindWives.FuRong(wife1);//  
     System.out.println("My wife will be :" + wife1.name); 
     
  执行结果呢?这里先买个关子,下面逐步来分析。
  眼下有三大奇女子“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的任何传说。
  所示,程序执行的结果是:
/*程序执行的结果 
My wife will be :FengJie 
My wife will be :白娘子 
*/ 
&
补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,