關于Java引用傳遞的一個困惑?
問題描述
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 stubint[] 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]; }}
這樣子我試了一下,就可以達到交換的目的了好困惑啊,求解!!
問題解答
回答1: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,看看結果。
回答2:swapEqual函數里面,只是改變了形參a、b的引用,并沒有改變實參c、d的引用。 而swap里面,改變的c、d對應的區域的值了。 補充一下,Java里面數組也是對象,所以a、b、c、d都是引用。
回答3:Java 里的引用和 C++ 里的引用概念有點不一樣,Java 里的引用相當于 C++ 中的指針,所以你直接對形參賦值是改變不了實參的。
回答4:看看這個回答。https://www.zhihu.com/questio...
回答5: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出來的對象占多大內存并不能確定,只能在運行期間才能分配,才能明白這個對象分配多大。 而且占用內存不能確定的原因還有一個就是,方法在執行的時候才分配內存。如果沒有調用方法,那方法只是一堆代碼而已,并不占用內存。
回答6:謝謝大家的回答,都講的挺好的。我也明白了
相關文章:
1. 一個走錯路的23歲傻小子的提問2. angular.js - angularjs 使用鼠標懸停時,標簽一直閃3. c++ - win764位環境下,我用GCC為什么指針占8個字節,而long是4個字節?4. html5 - HTML代碼中的文字亂碼是怎么回事?5. android - 安卓activity無法填充屏幕6. python 計算兩個時間相差的分鐘數,超過一天時計算不對7. python - django 里自定義的 login 方法,如何使用 login_required()8. javascript - SuperSlide.js火狐不兼容怎么回事呢9. node.js - 函數getByName()中如何使得co執行完后才return10. java - 安卓電視盒子取得了root權限但是不能安裝第三方應用,請問該怎么辦?
