java中的引用與c中的指標

我妻禮彌發表於2018-05-27

指標

      首先要弄清楚指標和c中的指標是不一樣的,前者是概念,後者是具體例項。

      換句話說,C中的指標只是指標中的一種,其他語言也有指標,比如C++。但是我們同別人交流的時候,大都不會從概念上去交流,一般會選擇其中一個例項去說,這個例項大部分時候都是C中的指標。久而久之,概念和例項被模糊化,C中的指標也成為了指標本身。

      在這裡我還是有必要給自己的大腦提個醒,不要將概念和例項混為一談,要分清兩者的界限。

指標定義

      既然這麼多語言都有自己的指標,那麼這個指標到底是什麼有沒有一個明確的定義。

java中的引用與c中的指標

這是維基百科上的解釋。

      一句話解釋就是 指標就是一個值,而這個值是某塊記憶體的地址,通過這個值,就可以找到這塊記憶體

C語言中的指標

C語言的指標具有以下特點

  • C語言的指標可以指向記憶體的任何地方。
  • C語言的指標可以參與數值運算,加法、減法。
  • C語言的指標還可以指向指標,以及指向指向指標的指標(因為指標就是一個值,也要存在記憶體中,所以它也有一個記憶體地址)

以上特點反映了指標尋地址的特性。

      另外,指標這個東西,只關心記憶體的地址,不關心記憶體存的是什麼東西,如果該地址中的物件被搬走了,指標不會自動改變指向。

Java中的引用

      在瞭解引用之前,首先讓我們先了解一下,java的引用型別。

      在JAVA中資料可以簡單分為兩種型別,基本型別引用型。繼續細分的話基本型別又可以分為四種整數型 byteshort、int、long 兩種浮點型float、double 一種字元型別char 一種布林型 boolean。引用型別可以說有無數種,包括String、陣列、object等等。

      在java種只有引用型才有引用

基本型別記憶體分配

      在基本型別中,你定義變數 int i = 0; 那麼它在記憶體裡的分配是這樣的:記憶體裡分配了一塊空間,這塊空間的名字是i,裡面的內容是0

java中的引用與c中的指標

當你使用i的時候就可以訪問這塊空間裡的內容。

引用型別記憶體分配

      與基本型別記憶體分配不同,引用型別在記憶體分配時,會分配兩塊記憶體,一塊儲存引用,一塊儲存值

      比如在定義String s; 或者String s = null; 時。系統會分配一塊記憶體用來引用值(在本例中裝的是空值null,也就是什麼也沒有裝)

java中的引用與c中的指標

      至於具體這個s(引用)分配在哪,要看他被宣告的位置。如果s被宣告為區域性變數,那s(引用)就在棧空間。如果不是區域性變數,那就不在棧上分配。

當你為s賦值的時候,s = new String("wqlm");

      情況發生了改變,引用有了一個明確的指向位置,引用的值也不再是空值。

java中的引用與c中的指標

      從上例可以看到在定義變數時引用沒有體,不佔空間,只有在變數賦值時,引用才有實際值

java引用的實質

從上面可以看出,java的引用和c的指標很相似

      java的引用也是一個值,但是這個值不是某塊記憶體的地址,而是某個值所在記憶體的地址。他關注的是值,當值搬家後,引用也會跟著改──記憶體碎片整理

     其實引用就是一個封裝過的指標,它遮蔽了指標的複雜性,在編譯器的實現中,引用最後還是會被轉成指標

java的引用與c的指標的區別

  • java的引用是某個值所在記憶體的地址。
  • c的指標是某塊記憶體的地址。
  • c的指標的值可以認為是個int型別,長度一般是計算機字長。
  • java的引用,宣告變數時(不賦值),不佔空間。(原因見引用型別記憶體分配)
  • java的引用初始值為 null。c的指標是int,如不初始化指標,那它的值就不是固定的了。
  • java的引用不可以計算。c的指標是int,他可以計算,如++或--,所以經常用指標來代替陣列下標。

番外·java的引用傳遞

java的方法在傳遞引數時,一般有兩種情況

  1. 引數是基本型別,直接將基本型別的值傳遞過來
  2. 引數是引用型別,將引數的引用值copy一份傳遞過來

因此,也可以說java只有值傳遞,所謂的引用傳遞,傳遞的是引用的值


相關文章