1. 程式人生 > >學習Java的引用型別時的一點心得二之引用變數

學習Java的引用型別時的一點心得二之引用變數

上篇我寫到類的靜態成員屬性(域、變數)是所有此類物件的共同特性,為此類所有的物件所共享;物件的成員屬性為每個用此類創建出的物件所獨有,不為其它物件所有。

那在這裡,我們多次提到一個詞——物件。首先在java中,物件是什麼呢?想在我所讀過的所有的書中都說過這樣一句話:一切皆物件。

我在這裡真有點不知所措,什麼叫:一切皆物件。這對於我來說,到現在也是感到頗為無奈。它就像是道可道,非常道和什麼佛曰:不可說一樣呀,讓人都一點頭腦都摸不到。

由上面的一段話,實際上也就暴露出:我對什麼是物件還是一腦子的疑惑。但就算是有疑惑,我也還是有一點自己的感覺和體悟的。就我的理解,什麼是物件呢?簡單點說是用new操作符去操作類檔案的結果就是一個物件。那更詳細和具體一點的呢?那就是能去用資料和語言描述的事情和物體(事、物)就是物件,這是我們的類檔案就是物件的文字描述。

因為心中存在關於類的物件在JVM是以什麼樣的形態存在的這樣的困惑,還有,為什麼同一類的不同的物件可以擁有相同的成員,是不是在物件建立時,為每一個物件都複製了一個成員名列表給這些物件,為什麼我們僅僅通過物件的飲用型變數就可以操作物件的可見成員等等這些問題就是我在學習引用變數時,所出現的困惑,但到現在我也沒有得到一個我所能滿意的解答。

我一直希望能有一個對類的物件在記憶體中的形態以及它的整體活動狀態的一個形象的、生動的解答,更期望能有一個直觀的圖形或者動畫的演示,若能把我的這些問題都能擬人化,讓它們動畫式的展示在面前就更好了。可以一直就是找不到這樣一個資源,所以也就只能退而求其次了。

下面是我在其他部落格中找到的一些我認為對我比較有幫助的,還算直觀的關於物件在JVM的形態的解答:

https://www.cnblogs.com/NeverCtrl-C/p/6486156.html
new 建立物件過程  此圖出自: https://www.cnblogs.com/NeverCtrl-C/p/6486156.html

 此篇部落格詳細介紹了物件的宣告週期:

物件的生命週期

  1.1 使用new運算子建立物件

    1.1.1 Java虛擬機器先檢查類是否載入, 如果沒有載入就載入類資訊到方法區

    1.1.2 根據類資訊中的屬性定義在堆記憶體中開闢儲存空間, 並且每個屬性有預設值

    1.1.3 呼叫構造器, 執行構造器中屬性初始化過程, 構造器結束時候, 釋放構造器中全部的區域性變數

    1.1.4 new運算返回物件的引用(即:物件在堆中的地址)

  1.2 利用引用操作使用物件 - 使用引用操作物件: 訪問物件的屬性和方法. - 可以反覆更改物件的屬性狀態.

  1.3 物件在不被引用時候被垃圾回收器回收 - 當一個物件不再被引用時候, 物件就稱為記憶體垃圾. 記憶體垃圾在適當時候被垃圾回收器回收.

  1.4 注意

    1.4.1 物件生存期中構造器只能執行一次. 在物件生存期間, 可以反覆呼叫其方法, 反覆訪問其屬性. 

    1.4.2 物件的屬性隨著物件在堆中分配.

 

在配合另一篇部落格來加深一下理解:

https://www.cnblogs.com/jimoer/p/8849025.html
此圖出自: https://www.cnblogs.com/jimoer/p/8849025.html

這張圖更加簡明的展示了物件與類檔案的關係,更直觀的說明了物件是如何操作物件的可見的成員(類的成員域和成員方法)的。

 

上面說了那麼多,都是在說類的物件的,好像與我的題目所要表達的主題似乎有些偏題了。但就我的理解,要向理解引用變數(物件的識別符號、物件的指標變數),那就必然有對物件有一個差強人意的理解不是。不然,我們在不不瞭解物件的執行狀態的情況下來去學習引用變數,那不是有點空中樓閣或只知其然,而不知其所然的感覺嗎?我的思路就是有引用變數,為什麼要有引用變數,以及引用變數如何作用於物件的,引用變數作用於物件後,物件又引起了哪些變化。我的這篇部落格,可以說是對這個思路的一個逆向說明。

上面說了物件在記憶體中的存在形態,下面就說一說引用型變數是如何標識它所引用的物件的。我們知道引用變數存在於stack中,通過上面的兩幅圖片,我們也能看出,引用變數指向了它所引用的物件。在Java教材中,我們也得知:引用變數儲存的是物件在heap中的首地址。

因此,當我們通過引用變數取訪問物件時,JVM就會通過此地址在heap中找到要訪問的物件。所以,我們就可以直接認為這個引用了該物件的變數就相當於該物件了,因為,我們每次去使用該變數時,JVM就會自動的找尋它所引用的物件。這就像我們的名字一樣,當我們說一個人的名字,我們就會自然而然的與此人做唯一性的關聯,不然我們說的這個名字還有什麼意義呢?實際是對於JVM與引用變數的性質也是如此,若我們對JVM說一個沒有引用物件的引用型變數,對於JVM來說,此變數就是無意義的,那麼JVM怎麼表示它無意義呢?就是給這個變數一個null值。

好了,現在,我們知道了,引用變數是物件的標誌,在程式碼中使用因為變數,在執行時,JVM便會自動的尋找到此變數所指向的物件。那後面的通過此變數來使用物件的可見的成員,此時我想便也是順理成章了呢。

感想:在學習這個內容時,讓我知道了有些問題間的包含性是很強的,當想理解被包含在內部的問題時,我們就要對包含此問題的外部問題有所瞭解,不然,若只是針對此問題,那便是有些費力不討好,花費了很長時間也還有可能是對問題一知半解,若理解有偏差,這也許可以用一句話道出其意:失之毫厘謬以千里。

只是在這裡,我還有兩個問題沒有被解決,那就是物件如何找到我們所要使用的成員的?JVM是怎樣按邏輯地址定址的?在此寫出我的這個問題,也是希望大家能給我一個指導,在此先做出感謝!