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]);
则完成了通过y对x的引用。从这个实际效果看,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的函数参数在传递的时候有两种方式。对于基本类型,如int,double等作为函数参数传递时,采取的是传值方式。而对于对象,如数组、字符串等作为参数传递时,采用的是引用方式,即此时在函数中对传递的对象的修改将完全影响原对象。那能否对于对象利用引用完成值的交换呢?下面的程序充分地演示了这个问题:
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的引用可以实现C和C++的指针的类似的效果,这在主函数中的引用交换得到了证明。但是一但进行了函数的参数传递,这种引用方式的交换便实效了。虽然它的交换方式和主函数中利用Object引用t进行的交换方式相同。猜测其原因(因为我不是Java的实现者),只能说明,函数中的引用变量和主函数中调用的变量是不相同的。即在调用swap函数时,虽然将x1的引用传递给了x,x2传递给了y,x和y进行了交换,但x1和x2并没有进行交换。也就是说,在函数swap申明参数x和y时,实际另外真正的生成了与x1和x2完全不相干的引用,只不过x和y都同样指向了x1和x2罢了,即此时,数组对象x1和x2同时分别有两个指针x、x1和y、y1指向它们。这样的结果当然不能完成如C和C++类似的交换。唯一的办法是如swapArray函数中一样,不要试图交换,只能试图修改参数所指向的两个对象的值来达到交换的效果。
所以我得出的一个相关的结论是:Java永远也不能实现如C和C++一样的swap函数。