Java中沒有了指針,這有時(shí)給程序員帶來了些許不便。Java的語言設(shè)計(jì)者強(qiáng)調(diào),這種不便可以通過Java的引用特性得到彌補(bǔ)。即對(duì)于Java的任何對(duì)象,我們可以申明對(duì)象變量,但不產(chǎn)生實(shí)例,這樣,把該變量指向具有實(shí)際實(shí)例的對(duì)象,即可實(shí)現(xiàn)同一實(shí)例對(duì)象的多個(gè)變量引用,如:
int x[]={1,2,3,4,5}, y[];
y=x;
for(int i=0; i<y.length; i++) System.out.print(“ ”+y[i]);
則完成了通過y對(duì)x的引用。從這個(gè)實(shí)際效果看,y在這里就很象C語言中的指針了。只不過對(duì)于“指針”y我們不能進(jìn)行+或-這類算數(shù)運(yùn)算,即Java的引用只能指向程序限定的能夠訪問的現(xiàn)存對(duì)象,所以Java的實(shí)現(xiàn)者認(rèn)為它是靈活同時(shí)也是安全的。
但對(duì)于C或者C++中能夠通過函數(shù)簡(jiǎn)單實(shí)現(xiàn)的兩個(gè)數(shù)交換問題,即C++如下函數(shù):
void swap(int &x, int &y) { int t; t=x; x=y; y=t; }
在Java中是否能夠?qū)崿F(xiàn)呢?
按照Java的規(guī)定,Java的函數(shù)參數(shù)在傳遞的時(shí)候有兩種方式。對(duì)于基本類型,如int,double等作為函數(shù)參數(shù)傳遞時(shí),采取的是傳值方式。而對(duì)于對(duì)象,如數(shù)組、字符串等作為參數(shù)傳遞時(shí),采用的是引用方式,即此時(shí)在函數(shù)中對(duì)傳遞的對(duì)象的修改將完全影響原對(duì)象。那能否對(duì)于對(duì)象利用引用完成值的交換呢?下面的程序充分地演示了這個(gè)問題:
public class test {
public static void main(String[] arg) {
int x1[]={1,2,3},x2[]={3,2,1};
swap(x1,x2);//采用swap函數(shù),即直接利用參數(shù)引用進(jìn)行交換
System.out.print("swap->X1:\t"); printarr(x1);
System.out.print("swap->X2:\t"); printarr(x2);
swapArray(x1,x2);//采用swapArray函數(shù),利用對(duì)于對(duì)象的值的修改進(jìn)行交換
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;//在非函數(shù)調(diào)用中直接利用引用進(jìn)行交換
System.out.print("Tswap->X1:\t"); printarr(x1);
System.out.print("Tswap->X2:\t"); printarr(x2);
}
public static void swap(Object x, Object y) {//直接利用參數(shù)引用交換
Object t=x;
x=y;
y=t;
}
public static void swapArray(int x[], int y[]) {//對(duì)引用對(duì)象的值進(jìn)行修改完成交換
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[]) {//打印數(shù)組
for(int i=0; i<x.length; i++) System.out.print(x[i]+" ");
System.out.println();
}
}
在函數(shù)swap中,我們直接利用參數(shù)進(jìn)行交換。在函數(shù)swapArray中,我們通過修改參數(shù)指向的兩個(gè)數(shù)組的值進(jìn)行交換。而在main函數(shù)沒有進(jìn)行函數(shù)參數(shù)傳遞的情況下,我們直接利用參數(shù)的引用進(jìn)行了一次交換。
程序的運(yùn)行結(jié)果如下:
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
從運(yùn)行結(jié)果我們可以清楚地看到,函數(shù)swap實(shí)際沒有完成交換,而函數(shù)swapArray和直接在main中利用引用進(jìn)行的交換是成功的。從這里我們可以得知,雖然Java的引用可以實(shí)現(xiàn)C和C++的指針的類似的效果,這在主函數(shù)中的引用交換得到了證明。但是一但進(jìn)行了函數(shù)的參數(shù)傳遞,這種引用方式的交換便實(shí)效了。雖然它的交換方式和主函數(shù)中利用Object引用t進(jìn)行的交換方式相同。猜測(cè)其原因(因?yàn)槲也皇?span lang="EN-US">Java的實(shí)現(xiàn)者),只能說明,函數(shù)中的引用變量和主函數(shù)中調(diào)用的變量是不相同的。即在調(diào)用swap函數(shù)時(shí),雖然將x1的引用傳遞給了x,x2傳遞給了y,x和y進(jìn)行了交換,但x1和x2并沒有進(jìn)行交換。也就是說,在函數(shù)swap申明參數(shù)x和y時(shí),實(shí)際另外真正的生成了與x1和x2完全不相干的引用,只不過x和y都同樣指向了x1和x2罷了,即此時(shí),數(shù)組對(duì)象x1和x2同時(shí)分別有兩個(gè)指針x、x1和y、y1指向它們。這樣的結(jié)果當(dāng)然不能完成如C和C++類似的交換。唯一的辦法是如swapArray函數(shù)中一樣,不要試圖交換,只能試圖修改參數(shù)所指向的兩個(gè)對(duì)象的值來達(dá)到交換的效果。
所以我得出的一個(gè)相關(guān)的結(jié)論是:Java永遠(yuǎn)也不能實(shí)現(xiàn)如C和C++一樣的swap函數(shù)。