關(guān)于Java引用傳遞的一個(gè)困惑?
問(wèn)題描述
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]); }
為什么打印出來(lái)的C[1]還是原來(lái)的2啊,為什么沒(méi)有交換。數(shù)組的=不就是復(fù)制引用嗎?通過(guò)函數(shù)可以把a(bǔ),b的引用交換,這樣不就是把內(nèi)容交換了嗎?干嘛非要這樣寫(xiě)?
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]; }}
這樣子我試了一下,就可以達(dá)到交換的目的了好困惑啊,求解!!
問(wèn)題解答
回答1:swapEqual(int[] a,int[] b)中:一開(kāi)始:a --> {1,2}(地址1)b --> {3,4}(地址2)經(jīng)過(guò)你的代碼處理(a,b指向的地址交換了):b --> {1,2}(地址1)a --> {3,4}(地址2)但是不會(huì)對(duì)c,d造成影響,c,d依舊是:c --> {1,2}(地址1)d --> {3,4}(地址2)
//=================================
swap(int[] a,int[] b)中:一開(kāi)始:a --> {1,2}(地址1)b --> {3,4}(地址2)經(jīng)過(guò)你的代碼處理(地址1,2中的值交換了):a --> {3,4}(地址1)b --> {1,2}(地址2)雖然不會(huì)對(duì)c,d指向的地址造成影響,但是原本地址下的值已經(jīng)改變了:c --> {3,4}(地址1)d --> {1,2}(地址2)
//=======================================
我的理解是這樣,寫(xiě)完發(fā)現(xiàn)與@lianera的表述是同一個(gè)意思,就當(dāng)是補(bǔ)充說(shuō)明了。
//=======================================
你可以嘗試用return把swapEqual(int[] a,int[] b)中交換后的a,b的值賦給c,d,看看結(jié)果。
回答2:swapEqual函數(shù)里面,只是改變了形參a、b的引用,并沒(méi)有改變實(shí)參c、d的引用。 而swap里面,改變的c、d對(duì)應(yīng)的區(qū)域的值了。 補(bǔ)充一下,Java里面數(shù)組也是對(duì)象,所以a、b、c、d都是引用。
回答3:Java 里的引用和 C++ 里的引用概念有點(diǎn)不一樣,Java 里的引用相當(dāng)于 C++ 中的指針,所以你直接對(duì)形參賦值是改變不了實(shí)參的。
回答4:看看這個(gè)回答。https://www.zhihu.com/questio...
回答5:Java的引用(包括基本類型,對(duì)象引用類型)在聲明、方法調(diào)用等時(shí)候都會(huì)產(chǎn)生新的引用,復(fù)制等號(hào)右側(cè)的引用。分為下面3種情況:
基本類型代表的值存儲(chǔ)在引用里面,引用中專門(mén)有個(gè)區(qū)域存儲(chǔ)這個(gè)值,所以在復(fù)制的時(shí)候,值也同時(shí)被復(fù)制了。
引用類型這個(gè)區(qū)域存儲(chǔ)的是對(duì)象在堆內(nèi)存中的內(nèi)存地址,引用復(fù)制的時(shí)候,指向的內(nèi)存地址卻是同一份,所以不會(huì)涉及值(也就是對(duì)象)的復(fù)制
數(shù)組里面都是存儲(chǔ)的引用(包括基本類型,對(duì)象引用類型)
引用信息:在Java中,引用數(shù)據(jù)類型占內(nèi)存嗎?
要弄清楚這個(gè)問(wèn)題,首先要清楚,在JAVA中有四類八種基本類型,除了基本類型,全都是引用類型。比如你寫(xiě) int i = 1; 那么它在內(nèi)存里的分配是這樣的:內(nèi)存里分配了一塊空間,這塊空間的名字是i,里面的內(nèi)容是1.
當(dāng)你使用i的時(shí)候就可以訪問(wèn)這塊空間里的內(nèi)容。而引用類型不同,引用類型在內(nèi)存中占兩塊內(nèi)存。比如:你寫(xiě)String s;或者String s = null;這時(shí)候在內(nèi)存里分配一塊內(nèi)存。這塊內(nèi)存裝的是空值null,也就是什么也沒(méi)有裝。因?yàn)檫€沒(méi)有進(jìn)行初始化。上個(gè)圖:
至于具體這個(gè)s分配在哪,要看他被聲明的位置。如果s被聲明為局部變量,那s就在棧空間。如果不是局部變量,那就不在棧上分配。而當(dāng)你用s指向一個(gè)String類型的對(duì)象的時(shí)候,就發(fā)生了變化。也就是接著寫(xiě)s = new String('zhihu');的時(shí)候。上個(gè)圖:
原來(lái)的s里面就會(huì)有一個(gè)值,根據(jù)s這塊空間里的這個(gè)值就可以找到在堆上找到另一塊內(nèi)存。所有new出來(lái)的東西都在堆內(nèi)存里。堆上的這塊內(nèi)存里對(duì)String的屬性進(jìn)行分配。堆內(nèi)存是動(dòng)態(tài)分配內(nèi)存的。所以既然是分配在堆上,其實(shí)也就說(shuō)明了new出來(lái)的對(duì)象占多大內(nèi)存并不能確定,只能在運(yùn)行期間才能分配,才能明白這個(gè)對(duì)象分配多大。 而且占用內(nèi)存不能確定的原因還有一個(gè)就是,方法在執(zhí)行的時(shí)候才分配內(nèi)存。如果沒(méi)有調(diào)用方法,那方法只是一堆代碼而已,并不占用內(nèi)存。
回答6:謝謝大家的回答,都講的挺好的。我也明白了
相關(guān)文章:
1. javascript - 在 vue里面用import引入js文件,結(jié)果為undefined2. html - 爬蟲(chóng)時(shí)出現(xiàn)“DNS lookup failed”,打開(kāi)網(wǎng)頁(yè)卻沒(méi)問(wèn)題,這是什么情況?3. 求教一個(gè)mysql建表分組索引問(wèn)題4. 小程序怎么加外鏈,語(yǔ)句怎么寫(xiě)!求救新手,開(kāi)文檔沒(méi)發(fā)現(xiàn)5. html5 - input type=’file’ 上傳獲取的fileList對(duì)象怎么存儲(chǔ)于瀏覽器?6. 求救一下,用新版的phpstudy,數(shù)據(jù)庫(kù)過(guò)段時(shí)間會(huì)消失是什么情況?7. python沒(méi)入門(mén),請(qǐng)教一個(gè)問(wèn)題8. php如何獲取訪問(wèn)者路由器的mac地址9. node.js - 用nodejs 的node-xlsx模塊去讀取excel中的數(shù)據(jù),可是讀取出來(lái)的日期是數(shù)字,請(qǐng)問(wèn)該如何讀取日期呢?10. javascript - 我的站點(diǎn)貌似被別人克隆了, google 搜索特定文章,除了域名不一樣,其他的都一樣,如何解決?
