更新時間:2020-09-09 來源:黑馬程序員 瀏覽量:
應用程序想要完成具體的功能,僅有類是遠遠不夠的,還需要根據類創建實例對象。在Java程序中,可以使用new關鍵字來創建對象,具體語法格式如下:
類名 對象名稱 = new 類名();
例如,創建Person類的實例對象代碼如下:
Person p = new Person();
上面的代碼中,“new Person()”用于創建Person類的一個實例對象,“Person p”則是聲明了一個Person類型的變量p,中間的等號用于將Person對象在內存中的地址賦值給變量p,這樣變量p便持有了對象的引用。為了便于描述,本書接下來的章節,通常會將變量p引用的對象簡稱為p對象。在內存中變量p和對象之間的引用關系如圖1所示。
從圖1可以看出,在創建Person對象時,程序會占用兩塊內存區域,分別是棧內存和堆內存。其中Person類型的變量p被存放在棧內存中,它是一個引用,會指向真正的對象;通過new Person()創建的對象則放在堆內存中,這才是真正的對象。
小提示:
Java將內存分為兩種,即棧內存和堆內存。其中棧內存用于存放基本類型的變量和對象的引用變量(如Person p),堆內存用于存放由new創建的對象和數組。
在創建Person對象后,可以通過對象的引用來訪問對象所有的成員,具體格式如下:
對象引用.對象成員
接下來通過一個案例來學習如何訪問對象的成員,如文件1所示。
文件1 Example02.java
public class Example02 { public static void main(String[] args) { Person p1 = new Person(); // 創建第一個Person類對象 Person p2 = new Person(); // 創建第二個Person類對象 p1.age = 18; // 為age屬性賦值 p1.speak(); // 調用對象的方法 p2.speak(); } }
運行結果如圖2所示。
圖2 運行結果
文件1中,p1、p2分別引用了Person類的兩個實例對象。從圖2可以看出,p1和p2對象在調用speak()方法時,打印的age值不同。這是因為p1對象和p2對象是兩個完全獨立的個體,它們分別擁有各自的age屬性,對p1對象的age屬性進行賦值并不會影響到p2對象age屬性的值。程序運行期間p1、p2引用的對象在內存中的狀態如圖3所示。
圖3 P1、P2對象在內存中的狀態
小提示:
在實際情況下,除了可以使用文件3-2中介紹的對象引用來訪問對象成員外,還可以直接使用創建的對象本身來引用對象成員,具體格式如下:
new 類名().對象成員
這種方式是在通過new關鍵字創建實例對象的同時就訪問了對象的某個成員,并且在創建后只能訪問其中某一個成員,而不能像對象引用那樣可以訪問多個對象成員。同時,由于沒有對象引用的存在,在完成某一個對象成員的訪問后,該對象就會變成垃圾對象。所以,在實際開發中,創建實例對象時多數會使用對象引用。
在文件1中,通過“p1.age=18”將p1對象的age屬性賦值為18,但并沒有對p2對象的age屬性進行賦值,按理說p2對象的age屬性應該是沒有值的。但從圖2可以看出,p2對象的age屬性也是有值的,其值為0。這是因為在實例化對象時,Java虛擬機會自動為成員變量進行初始化,針對不同類型的成員變量賦予不同的初始值,如表1所示。
表1 成員變量的初始化值
當對象被實例化后,在程序中可以通過對象的引用變量來訪問該對象的成員。需要注意的是,當沒有任何變量引用這個對象時,它將成為垃圾對象,不能再被使用。接下來通過兩段程序代碼來分析對象是如何成為垃圾的。
第一段程序代碼:
{ Person p1 = new Person(); ......}
上面的代碼中,使用變量p1引用了一個Person類型的對象。當這段代碼運行完畢時,變量p1就會超出其作用域而被銷毀,這時Person類型的對象將因為沒有被任何變量所引用而變成垃圾。
第二段程序代碼:
{ Person p2 = new Person(); ...... p2 = null; ......}
上面的代碼中,使用變量p2引用了一個Person類型的對象,接著將變量p2的值置為null,則表示該變量不指向任何一個對象,被p2所引用的Person對象就會失去引用,成為垃圾對象,過程如圖4所示。
猜你喜歡: