亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java基礎(chǔ)教程之對象引用

 更新時間:2014年09月01日 11:36:03   投稿:junjie  
這篇文章主要介紹了Java基礎(chǔ)教程之對象引用,“對象引用”(object reference)是一個重要重要概念,涉及內(nèi)存,需要的朋友可以參考下

我們之前一直在使用“對象”這個概念,但沒有探討對象在內(nèi)存中的具體存儲方式。這方面的討論將引出“對象引用”(object reference)這一重要概念。

對象引用

我們沿用之前定義的Human類,并有一個Test類:

復(fù)制代碼 代碼如下:

public class Test
{
    public static void main(String[] args)
    {
        Human aPerson = new Human(160);                
    }
}

class Human
{  
    /**
     * constructor
     */
    public Human(int h)
    {
        this.height = h;
    }

    /**
     * accessor
     */
    public int getHeight()
    {
       return this.height;
    }

    /**
     * mutator
     */
    public void growHeight(int h)
    {
        this.height = this.height + h;
    }

    private int height;
}


外部可以調(diào)用類來創(chuàng)建對象,比如上面在Test類中:

復(fù)制代碼 代碼如下:

Human aPerson = new Human(160);

創(chuàng)建了一個Human類的對象aPerson。

上面是一個非常簡單的表述,但我們有許多細(xì)節(jié)需要深入:

1.首先看等號的右側(cè)。new是在內(nèi)存中為對象開辟空間。具體來說,new是在內(nèi)存的堆(heap)上為對象開辟空間。這一空間中,保存有對象的數(shù)據(jù)和方法。

2.再看等號的左側(cè)。aPerson指代一個Human對象,被稱為對象引用(reference)。實(shí)際上,aPerson并不是對象本身,而是類似于一個指向?qū)ο蟮闹羔?。aPerson存在于內(nèi)存的棧(stack)中。

3.當(dāng)我們用等號賦值時,是將右側(cè)new在堆中創(chuàng)建對象的地址賦予給對象引用。

這里的內(nèi)存,指的是JVM (Java Virtual Machine)虛擬出來的Java進(jìn)程內(nèi)存空間。內(nèi)存的堆和棧概念可參考Linux從程序到進(jìn)程。

棧的讀取速度比堆快,但棧上存儲的數(shù)據(jù)受到有效范圍的限制。在C語言中,當(dāng)一次函數(shù)調(diào)用結(jié)束時,相應(yīng)的棧幀(stack frame)要刪除,棧幀上存儲的參量和自動變量就消失了。Java的棧也受到同樣的限制,當(dāng)一次方法調(diào)用結(jié)束,該方法存儲在棧上的數(shù)據(jù)將清空。在 Java中,所有的(普通)對象都儲存在堆上。因此,new關(guān)鍵字的完整含義是,在堆上創(chuàng)建對象。

基本類型(primitive type)的對象,比如int, double,保存在棧上。當(dāng)我們聲明基本類型時,不需要new。一旦聲明,Java將在棧上直接存儲基本類型的數(shù)據(jù)。所以,基本類型的變量名表示的是數(shù)據(jù)本身,不是引用。

引用和對象的關(guān)系就像風(fēng)箏和人。我們看天空時(程序里寫的),看到的是風(fēng)箏(引用),但風(fēng)箏下面對應(yīng)的,是人(對象):

引用和對象分離;引用指向?qū)ο?/p>

盡管引用和對象是分離的,但我們所有通往對象的訪問必須經(jīng)過引用這個“大門”,比如以 引用.方法() 的方式訪問對象的方法。在Java中,我們不能跳過引用去直接接觸對象。再比如,對象a的數(shù)據(jù)成員如果是一個普通對象b,a的數(shù)據(jù)成員保存的是指向?qū)ο骲的引用 (如果是基本類型變量,那么a的數(shù)據(jù)成員保存的是基本類型變量本身了)。

在Java中,引用起到了指針的作用,但我們不能直接修改指針的值,比如像C語言那樣將指針值加1。我們只能通過引用執(zhí)行對對象的操作。這樣的設(shè)計避免了許多指針可能引起的錯誤。

引用的賦值

當(dāng)我們將一個引用賦值給另一個引用時,我們實(shí)際上復(fù)制的是對象的地址。兩個引用將指向同一對象。比如 dummyPerson=aPerson;,將導(dǎo)致:

一個對象可以有多個引用 (一個人可以放多個風(fēng)箏)。當(dāng)程序通過某個引用修改對象時,通過其他引用也可以看到該修改。我們可以用以下Test類來測試實(shí)際效果:

復(fù)制代碼 代碼如下:

public class Test
{
    public static void main(String[] args)
        {
             Human aPerson = new Human(160);
             Human dummyPerson = aPerson;
             System.out.println(dummyPerson.getHeight());
             aPerson.growHeight(20);
             System.out.println(dummyPerson.getHeight());
        }
}

我們對aPerson的修改將影響到dummyPerson。這兩個引用實(shí)際上指向同一對象。

所以,將一個引用賦值給另一個引用,并不能復(fù)制對象本身。我們必須尋求其他的機(jī)制來復(fù)制對象。

垃圾回收

隨著方法調(diào)用的結(jié)束,引用和基本類型變量會被清空。由于對象存活于堆,所以對象所占據(jù)的內(nèi)存不會隨著方法調(diào)用的結(jié)束而清空。進(jìn)程空間可能很快被不斷創(chuàng)建的對象占滿。Java內(nèi)建有垃圾回收(garbage collection)機(jī)制,用于清空不再使用的對象,以回收內(nèi)存空間。

垃圾回收的基本原則是,當(dāng)存在引用指向某個對象時,那么該對象不會被回收; 當(dāng)沒有任何引用指向某個對象時,該對象被清空。它所占據(jù)的空間被回收。

上圖假設(shè)了某個時刻JVM中的內(nèi)存狀態(tài)。Human Object有三個引用: 來自棧的aPerson和dummyPerson,以及另一個對象的數(shù)據(jù)成員president。而Club Object沒有引用。如果這個時候垃圾回收啟動,那么Club Object將被清空,而Human Object來自Club Object的引用(president)也隨之被刪除。

垃圾回收是Java中重要的機(jī)制,它直接影響了Java的運(yùn)行效率。我將在以后深入其細(xì)節(jié)。

參數(shù)傳遞

當(dāng)我們分離了引用和對象的概念后,Java方法的參數(shù)傳遞機(jī)制實(shí)際上非常清晰: Java的參數(shù)傳遞為值傳遞。也就是說,當(dāng)我們傳遞一個參數(shù)時,方法將獲得該參數(shù)的一個拷貝。

實(shí)際上,我們傳遞的參數(shù),一個是基本類型的變量,另一個為對象的引用。

基本類型變量的值傳遞,意味著變量本身被復(fù)制,并傳遞給Java方法。Java方法對變量的修改不會影響到原變量。

引用的值傳遞,意味著對象的地址被復(fù)制,并傳遞給Java方法。Java方法根據(jù)該引用的訪問將會影響對象。

在這里有另一個值得一提的情況: 我們在方法內(nèi)部使用new創(chuàng)建對象,并將該對象的引用返回。如果該返回被一個引用接收,由于對象的引用不為0,對象依然存在,不會被垃圾回收。

總結(jié)

new

引用,對象

被垃圾回收的條件

參數(shù): 值傳遞

相關(guān)文章

最新評論