對象引用與對象的區別(轉載)

 初學Java時,在很長一段時間裏,總以爲基本概念很模糊。後來才知道,在許多Java書中,把對象和對象的引用混爲一談。但是,若是我分不清對象與對象引用,那實在無法很好地理解下面的面向對象技術。把本身的一點認識寫下來,或許能讓初學Java的朋友們少走一點彎路。java

       爲便於說明,咱們先定義一個簡單的類:web

       class Vehicle {函數

int passengers;      spa

int fuelcap;code

int mpg;orm

}對象

有了這個模板,就能夠用它來建立對象:字符串

       Vehicle veh1 = new Vehicle();it

一般把這條語句的動做稱之爲建立一個對象,其實,它包含了四個動做。模板

1)右邊的「new Vehicle」,是以Vehicle類爲模板,在堆空間裏建立一個Vehicle類對象(也簡稱爲Vehicle對象)。

2)末尾的()意味着,在對象建立後,當即調用Vehicle類的構造函數,對剛生成的對象進行初始化。構造函數是確定有的。若是你沒寫,Java會給你補上一個默認的構造函數。

3)左邊的「Vehicle veh1」建立了一個Vehicle類引用變量。所謂Vehicle類引用,就是之後能夠用來指向Vehicle對象的對象引用。

4)「=」操做符使對象引用指向剛建立的那個Vehicle對象。

咱們能夠把這條語句拆成兩部分:

Vehicle veh1;

veh1 = new Vehicle();

效果是同樣的。這樣寫,就比較清楚了,有兩個實體:一是對象引用變量,一是對象自己。

       在堆空間裏建立的實體,與在數據段以及棧空間裏建立的實體不一樣。儘管它們也是確確實實存在的實體,可是,咱們看不見,也摸不着。不只如此,咱們仔細研究一下第二句,找找剛建立的對象叫什麼名字?有人說,它叫「Vehicle」。不對,「Vehicle」是類(對象的建立模板)的名字。一個Vehicle類能夠據此建立出無數個對象,這些對象不可能全叫「Vehicle」。

       對象連名都沒有,無法直接訪問它。咱們只能經過對象引用來間接訪問對象。

       爲了形象地說明對象、引用及它們之間的關係,能夠作一個或許不很穩當的比喻。對象比如是一隻很大的氣球,大到咱們抓不住它。引用變量是一根繩,能夠用來系汽球。

       若是隻執行了第一條語句,還沒執行第二條,此時建立的引用變量veh1還沒指向任何一個對象,它的值是null。引用變量能夠指向某個對象,或者爲null。它是一根繩,一根尚未繫上任何一個汽球的繩。執行了第二句後,一隻新汽球作出來了,並被系在veh1這根繩上。咱們抓住這根繩,就等於抓住了那隻汽球。

       再來一句:

       Vehicle veh2;

就又作了一根繩,還沒繫上汽球。若是再加一句:

       veh2 = veh1;

繫上了。這裏,發生了複製行爲。可是,要說明的是,對象自己並無被複制,被複制的只是對象引用。結果是,veh2也指向了veh1所指向的對象。兩根繩系的是同一只汽球。

       若是用下句再建立一個對象:

veh2 = new Vehicle();

則引用變量veh2改指向第二個對象。

       從以上敘述再推演下去,咱們能夠得到如下結論:(1)一個對象引用能夠指向0個或1個對象(一根繩子能夠不繫汽球,也能夠系一個汽球);(2)一個對象能夠有N個引用指向它(能夠有N條繩子繫住一個汽球)。

       若是再來下面語句:

       veh1 = veh2;

按上面的推斷,veh1也指向了第二個對象。這個沒問題。問題是第一個對象呢?沒有一條繩子繫住它,它飛了。多數書裏說,它被Java的垃圾回收機制回收了。這不確切。正確地說,它已成爲垃圾回收機制的處理對象。至於何時真正被回收,那要看垃圾回收機制的心情了。

       由此看來,下面的語句應該不合法吧?至少是沒用的吧?

new Vehicle();

不對。它是合法的,並且可用的。譬如,若是咱們僅僅爲了打印而生成一個對象,就不須要用引用變量來繫住它。最多見的就是打印字符串:

       System.out.println(「I am Java!」);

字符串對象「I am Java!」在打印後即被丟棄。有人把這種對象稱之爲臨時對象。

對象與引用的關係將持續到對象回收。可是,關於這一點,打算在下文「簡述Java回收機制」再說。

相關文章
相關標籤/搜索