指標
首先要弄清楚指標和c中的指標是不一樣的,前者是概念,後者是具體例項。
換句話說,C中的指標只是指標中的一種,其他語言也有指標,比如C++。但是我們同別人交流的時候,大都不會從概念上去交流,一般會選擇其中一個例項去說,這個例項大部分時候都是C中的指標。久而久之,概念和例項被模糊化,C中的指標也成為了指標本身。
在這裡我還是有必要給自己的大腦提個醒,不要將概念和例項混為一談,要分清兩者的界限。
指標定義
既然這麼多語言都有自己的指標,那麼這個指標到底是什麼有沒有一個明確的定義。
這是維基百科上的解釋。
一句話解釋就是 指標就是一個值,而這個值是某塊記憶體的地址,通過這個值,就可以找到這塊記憶體
C語言中的指標
C語言的指標具有以下特點
- C語言的指標可以指向記憶體的任何地方。
- C語言的指標可以參與數值運算,加法、減法。
- C語言的指標還可以指向指標,以及指向指向指標的指標(因為指標就是一個值,也要存在記憶體中,所以它也有一個記憶體地址)
以上特點反映了指標尋地址的特性。
另外,指標這個東西,只關心記憶體的地址,不關心記憶體存的是什麼東西,如果該地址中的物件被搬走了,指標不會自動改變指向。
Java中的引用
在瞭解引用之前,首先讓我們先了解一下,java的引用型別。
在JAVA中資料可以簡單分為兩種型別,基本型別和引用類型。繼續細分的話基本型別又可以分為四種整數型 byte、short、int、long 兩種浮點型float、double 一種字元型別char 一種布林型 boolean。引用型別可以說有無數種,包括String、陣列、object等等。
在java種只有引用類型才有引用
基本型別記憶體分配
在基本型別中,你定義變數 int i = 0; 那麼它在記憶體裡的分配是這樣的:記憶體裡分配了一塊空間,這塊空間的名字是i,裡面的內容是0
當你使用i的時候就可以訪問這塊空間裡的內容。
引用型別記憶體分配
與基本型別記憶體分配不同,引用型別在記憶體分配時,會分配兩塊記憶體,一塊儲存引用,一塊儲存值。
比如在定義String s; 或者String s = null; 時。系統會分配一塊記憶體用來引用值(在本例中裝的是空值null,也就是什麼也沒有裝)
至於具體這個s(引用)分配在哪,要看他被宣告的位置。如果s被宣告為區域性變數,那s(引用)就在棧空間。如果不是區域性變數,那就不在棧上分配。
當你為s賦值的時候,s = new String("wqlm");
情況發生了改變,引用有了一個明確的指向位置,引用的值也不再是空值。
從上例可以看到在定義變數時,引用沒有實體,不佔空間,只有在變數賦值時,引用才有實際值
java引用的實質
從上面可以看出,java的引用和c的指標很相似
java的引用也是一個值,但是這個值不是某塊記憶體的地址,而是某個值所在記憶體的地址。他關注的是值,當值搬家後,引用也會跟著改──記憶體碎片整理
其實引用就是一個封裝過的指標,它遮蔽了指標的複雜性,在編譯器的實現中,引用最後還是會被轉成指標
java的引用與c的指標的區別
- java的引用是某個值所在記憶體的地址。
- c的指標是某塊記憶體的地址。
- c的指標的值可以認為是個int型別,長度一般是計算機字長。
- java的引用,宣告變數時(不賦值),不佔空間。(原因見引用型別記憶體分配)
- java的引用初始值為 null。c的指標是int,如不初始化指標,那它的值就不是固定的了。
- java的引用不可以計算。c的指標是int,他可以計算,如++或--,所以經常用指標來代替陣列下標。
番外·java的引用傳遞
java的方法在傳遞引數時,一般有兩種情況
- 引數是基本型別,直接將基本型別的值傳遞過來
- 引數是引用型別,將引數的引用值copy一份傳遞過來
因此,也可以說java只有值傳遞,所謂的引用傳遞,傳遞的是引用的值