歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java中類與對象的生命周期

Java中類與對象的生命周期

日期:2017/3/1 10:09:56   编辑:Linux編程

類的生命周期

.java源文件經過編譯後會生成相應的字節碼文件(.class)。jvm通過解釋器翻譯字節碼文件並在系統中執行。

而java類的生命周期就是其字節碼文件裝載、連接、初始化、使用、和卸載的整個過程。

裝載。
jvm找到需要裝載的類,將類的信息裝載到jvm的方法區中。然後在堆區實例化一個java.lang.Class對象,作為方法區中的類的信息入口。

不同的jvm對於類的裝載時機並不相同,有些在遇到這個類時就裝載這個類(雖然並不知道這個類是否會被用到),另一些則在真正用到一個類的時候才對它進行裝載。

連接階段。連接階段一般情況下在一個類加載了一部分之後就開始,與裝載階段交叉進行。連接階段主要做一些加載後的驗證以及初始化的准備工作,分為驗證、准備、解析三個子階段。

驗證主要是驗證一個被加載的類是否合法,以確保這個類能夠被jvm運行。
准備階段為類中的靜態變量分配內存和jvm默認初值(不是程序中設定的初值。對於jvm,基本類型的默認處置為0,而引用類型為null),並為常量分配我們在程序中設定的初值。
解析是指把常量池中的符號引用轉換為直接引用,即將所有的類名、接口名、字段名、方法名轉換為具體的內存地址。


如果一個類被直接引用,則會觸發類的初始化。被動引用則不會觸發類的初始化。

直接引用的情況有:

創建類的新實例
調用類的靜態方法
操作類或接口的靜態字段(final字段除外)
調用Java的特定的反射方法
初始化一個類的子類
指定一個類作為Java虛擬機啟動時的初始化類
初始化過程會初始化與類相關的賦值語句和靜態語句(即有static關鍵字修飾的信息),其他語句在實例化對象的時候才會運行。

初始化按照順序運行類中的賦值語句和靜態語句。如果有父類,則首首先運行父類中的語句。

以下情況不會引起類的初始化:

定義類數組

SampleClass[] samples = new SampleClass[5];

引用類的常量

String sampleConstant = SampleClass.SampleConstant;

使用
類的使用包括主動引用和被動引用。只有主動引用會實例化類對象。
卸載
如果下面的所有情況都成立,類將會被卸載:
類所有的實例都已經被回收。(即堆中不存在該類的任何實例)
加載該類的ClassLoader被回收。
該類對應的java.lang.Class對象沒有任何地方被引用,無法在任何地方通過反射訪問該類的方法。
jvm在方法區垃圾回收的時候對類進行卸載,在方法區中清空類信息。

至此,一個java類的生命周期結束。

對象的生命周期

java對象是在jvm的堆區創建的。在創建對象之前,可能會觸發類的加載、連接和初始化。

jvm在類初始化完成後,根據類的信息在堆區實例化類對象,初始化非靜態變量和默認構造方法。

由於java在堆上創建對象,因此編譯器對對象的生命周期一無所知。Java提供了垃圾回收器機制,jvm會在空閒時間以不定時的方式動態回收無任何引用的對象占據的內存空間。

Copyright © Linux教程網 All Rights Reserved