woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 0
数据加载中……

关于Java的引用和函数参数传递

Java中没有了指针,这有时给程序员带来了些许不便。Java的语言设计者强调,这种不便可以通过Java的引用特性得到弥补。即对于Java的任何对象,我们可以申明对象变量,但不产生实例,这样,把该变量指向具有实际实例的对象,即可实现同一实例对象的多个变量引用,如:

int x[]={1,2,3,4,5}, y[];

y=x;

for(int i=0; i<y.length; i++) System.out.print(“   ”+y[i]);

则完成了通过yx的引用。从这个实际效果看,y在这里就很象C语言中的指针了。只不过对于“指针”y我们不能进行+-这类算数运算,即Java的引用只能指向程序限定的能够访问的现存对象,所以Java的实现者认为它是灵活同时也是安全的。

但对于C或者C++中能够通过函数简单实现的两个数交换问题,即C++如下函数:

void swap(int &x, int &y) { int t; t=x; x=y; y=t; }

Java中是否能够实现呢?

按照Java的规定,Java的函数参数在传递的时候有两种方式。对于基本类型,如intdouble等作为函数参数传递时,采取的是传值方式。而对于对象,如数组、字符串等作为参数传递时,采用的是引用方式,即此时在函数中对传递的对象的修改将完全影响原对象。那能否对于对象利用引用完成值的交换呢?下面的程序充分地演示了这个问题:

public class test {

  public static void main(String[] arg) {

    int x1[]={1,2,3},x2[]={3,2,1};

    swap(x1,x2);//采用swap函数,即直接利用参数引用进行交换

    System.out.print("swap->X1:\t"); printarr(x1);

    System.out.print("swap->X2:\t"); printarr(x2);

    swapArray(x1,x2);//采用swapArray函数,利用对于对象的值的修改进行交换

    System.out.print("swapArr->X1:\t"); printarr(x1);

System.out.print("swapArr->X2:\t"); printarr(x2);

Object t;

    t=x1; x1=x2; x2=(int[])t;//在非函数调用中直接利用引用进行交换

    System.out.print("Tswap->X1:\t"); printarr(x1);

    System.out.print("Tswap->X2:\t"); printarr(x2);

  }

  public static void swap(Object x, Object y) {//直接利用参数引用交换

    Object t=x;

    x=y;

    y=t;

  }

  public static void swapArray(int x[], int y[]) {//对引用对象的值进行修改完成交换

    if(x.length!=y.length) return;

    int t[]=x.clone();

    for(int i=0; i<x.length; i++) x[i]=y[i];

    for(int i=0; i<y.length; i++) y[i]=t[i];

  }

  public static void printarr(int x[]) {//打印数组

    for(int i=0; i<x.length; i++) System.out.print(x[i]+"  ");

    System.out.println();

  }

}

在函数swap中,我们直接利用参数进行交换。在函数swapArray中,我们通过修改参数指向的两个数组的值进行交换。而在main函数没有进行函数参数传递的情况下,我们直接利用参数的引用进行了一次交换。

程序的运行结果如下:

swap->X1:     1  2  3 

swap->X2:     3  2  1 

swapArr->X1: 3  2  1 

swapArr->X2: 1  2  3 

Tswap->X1:   1  2  3 

Tswap->X2:   3  2  1 

从运行结果我们可以清楚地看到,函数swap实际没有完成交换,而函数swapArray和直接在main中利用引用进行的交换是成功的。从这里我们可以得知,虽然Java的引用可以实现CC++的指针的类似的效果,这在主函数中的引用交换得到了证明。但是一但进行了函数的参数传递,这种引用方式的交换便实效了。虽然它的交换方式和主函数中利用Object引用t进行的交换方式相同。猜测其原因(因为我不是Java的实现者),只能说明,函数中的引用变量和主函数中调用的变量是不相同的。即在调用swap函数时,虽然将x1的引用传递给了xx2传递给了yxy进行了交换,但x1x2并没有进行交换。也就是说,在函数swap申明参数xy时,实际另外真正的生成了与x1x2完全不相干的引用,只不过xy都同样指向了x1x2罢了,即此时,数组对象x1x2同时分别有两个指针xx1yy1指向它们。这样的结果当然不能完成如CC++类似的交换。唯一的办法是如swapArray函数中一样,不要试图交换,只能试图修改参数所指向的两个对象的值来达到交换的效果。

所以我得出的一个相关的结论是:Java永远也不能实现如CC++一样的swap函数。

 

posted on 2009-07-24 12:09 肥仔 阅读(1343) 评论(0)  编辑 收藏 引用 所属分类: Web-后台


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理