JVM學(xué)習(xí)筆記(2)——類型生命周期
直奔主題吧
- 一個(gè)java類經(jīng)過(guò)裝載、連接和初始化三步達(dá)到程序可用狀態(tài),其中連接又包含驗(yàn)證、準(zhǔn)備和可選的解析過(guò)程,驗(yàn)證是檢查數(shù)據(jù)格式、準(zhǔn)備是分配內(nèi)存、解析負(fù)責(zé)把常量池的符號(hào)引用轉(zhuǎn)換為直接引用。
- jvm必須在每個(gè)類或接口首次主動(dòng)使用時(shí)初始化,有六種主動(dòng)使用場(chǎng)景:1)創(chuàng)建某個(gè)類的新實(shí)例,2)調(diào)用某個(gè)類的靜態(tài)方法,3)使用某個(gè)類或接口的靜態(tài)字段,用final修飾的靜態(tài)字段除外,它被初始化為一個(gè)編譯時(shí)的常量表達(dá)式,4)調(diào)用Java api中的某些反射方法,5)初始化某個(gè)類的子類,6)虛擬機(jī)啟動(dòng)時(shí)某個(gè)被標(biāo)明為啟動(dòng)類的類(含有main方法的類)。
- 某個(gè)類要初始化,其所有的祖先類必須之前被初始化;接口則不同,只有在某個(gè)接口聲明的非常量字段被使用時(shí),該接口才初始化。
- 類裝載的三個(gè)基本動(dòng)作:通過(guò)完全限定名找到二進(jìn)制數(shù)據(jù)流,解析為方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu),創(chuàng)建一個(gè)該類型的java.lang.Class的實(shí)例。
- 類裝載有可能存在預(yù)先裝載,在預(yù)先裝載時(shí)出問(wèn)題,會(huì)拋出一個(gè)LinkageError的異常。
- 在準(zhǔn)備階段,內(nèi)存分配是初始化為默認(rèn)值的,而不是實(shí)際的初始值。默認(rèn)值列表如下:
類型 默認(rèn)初始值 int 0 long 0L short (short)0 char '\u0000' byte (byte)0 boolean false reference null float 0.0f double 0.0d - 在準(zhǔn)備和解析完后,才進(jìn)入初始化階段,為變量賦予真正的初始值。
- 初始化類的步驟:1)如果類存在直接超類,且直接超類還沒(méi)有被初始化,就先初始化直接超類。2)如果類存在一個(gè)類初始化方法,就執(zhí)行此方法。
- 第一個(gè)被初始化的類永遠(yuǎn)都是Object。
- 所有的類變量初始化語(yǔ)句和類型的靜態(tài)初始化器都被java編譯器收集在一起,放到一個(gè)特殊的方法中——<clinit>。
- 如果接口包含任何不能在編譯時(shí)被解析成為一個(gè)常量的字段初始化語(yǔ)句,接口就會(huì)擁有一個(gè)<clinit>方法。
- 類變量如果直接賦常量值,那么類是不會(huì)初始化的。
- 類實(shí)例化的四種途徑:1)new操作符。2)調(diào)用Class或Constructor的newInstance()方法。3)調(diào)用任何現(xiàn)有對(duì)象的clone()方法。4)通過(guò)ObjectInputStream的readObject()方法反序列化。
- JVM為它編譯的每一個(gè)類都至少生成一個(gè)實(shí)例初始化方法<init>。
- 使用啟動(dòng)類裝載器裝載的類,永遠(yuǎn)都不會(huì)被垃圾收集。
posted on 2012-09-19 18:13 changedi 閱讀(391) 評(píng)論(0) 編輯 收藏 所屬分類: Java技術(shù)