public static void swapEqual(int[] a,int[] b){
int[] temp=new int[b.length];
temp=b;
b=a;
a=temp;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] c={1,2};
int[] d={3,4};
swapEqual(c,d);
System.out.println(c[1]);
}
为什么打印出来的C[1]还是原来的2啊,为什么没有交换。数组的=不就是复制引用吗?通过函数可以把a,b的引用交换,这样不就是把内容交换了吗?
干嘛非要这样写?
public static void swap(int[] a,int[] b){
int[] temp=new int[b.length];
for(int i=0;i<b.length;i++){
temp[i]=b[i];
}
for(int i=0;i<b.length;i++){
b[i]=a[i];
}
for(int i=0;i<b.length;i++){
a[i]=temp[i];
}
}
这样子我试了一下,就可以达到交换的目的了
好困惑啊,求解!!
PHPz2017-04-18 10:49:30
swapEqual(int[] a,int[] b)中:
一開始:
a --> {1,2}(地址1)
b --> {3,4}(地址2)
經過你的程式碼處理(a,b指向的位址交換了):
b --> {1,2}(位址1)
a --> {3,4}(位址2)
但是不會對c,d造成影響,c,d依舊是:
c --> {1,2}(位址1)
d --> {3,4}(位址2)
//=================================
swap(int[] a,int[] b)中:
一開始:
a --> {1,2}(地址1)
b --> {3,4}(地址2)
經過你的代碼處理(地址1,2中的值交換了):
a --> {3,4}(地址1)
b --> {1,2}(地址2)
雖然不會對c, d指向的位址造成影響,但原本位址下的值已經改變了:
c --> {3,4}(位址1)
d --> {1,2}(位址2)
//=======================================
我的理解是這樣,寫完發現與@lianera的表述是同一個意思,就當是補充說明了。
//=======================================
你可以試著用return把swapEqual(int[] a,int[] b)交換後的a,b的值賦給c,d,看看結果。
PHP中文网2017-04-18 10:49:30
swapEqual函數裡面,只是改變了形參a、b的引用,並沒有改變實參c、d的引用。
而swap裡面,改變的c、d對應的區域的值了。
補充一下,Java裡面數組也是對象,所以a、b、c、d都是引用。
阿神2017-04-18 10:49:30
Java的引用(包括基本型別,物件引用型別)在宣告、方法呼叫等時候都會產生新的引用,複製等號右邊的引用。分為下面3種情況:
基本類型代表的值儲存在引用裡面,引用中專門有個區域儲存這個值,所以在複製的時候,值也同時被複製了。
引用型這個區域儲存的是物件在堆記憶體中的記憶體位址,引用複製的時候,指向的記憶體位址卻是同一份,所以不會涉及值(也就是物件)的複製
數組裡面都是儲存的引用(包括基本型,物件引用型別)
引用資訊:在Java中,引用資料型別佔記憶體嗎?
要弄清楚這個問題,首先要清楚,在JAVA中有四類八種基本類型,除了基本類型,全都是引用類型。例如你寫 int i = 1;
那麼它在記憶體裡的分配是這樣的:記憶體裡分配了一塊空間,這塊空間的名字是i,裡面的內容是1.
當你使用i的時候就可以存取這塊空間裡的內容。而引用型別不同,引用型別在記憶體中佔兩塊記憶體。例如:你寫String s;或String s = null;這時候在記憶體裡分配一塊記憶體。這塊記憶體裝的是空值null,也就是什麼都沒有裝。因為還沒有進行初始化。上個圖:
至於具體這個s分配在哪,要看他被聲明的位置。如果s被宣告為局部變量,那s就在堆疊空間。如果不是局部變量,那就不在堆疊上分配。而當你用s指向一個String類型的物件的時候,就改變了。也就是接著寫s = new String("zhihu");的時候。上個圖:
原來的s裡面就會有一個值,根據s這塊空間裡的這個值就可以找到在堆上找到另一塊記憶體。所有new出來的東西都在堆記憶體裡。堆上的這塊記憶體裡對String的屬性進行分配。堆記憶體是動態分配記憶體的。所以既然是分配在堆上,其實也說明了new出來的物件佔多大記憶體並不能確定,只能在運作期間才能分配,才能明白這個物件分配多大。 而且佔用記憶體不能確定的原因還有一個就是,方法在執行的時候才分配記憶體。如果沒有呼叫方法,那方法只是一堆程式碼而已,不佔用記憶體。