最近又重新研讀了《深入理解Java虛擬機》,其中一個知識點在這裏記錄一下。
類的成員變量有默認初始值,而方法內的局部變量卻沒有初始值。這個問題涉及到JVM類加載和字節碼執行兩個階段,這兩個階段是依次執行的。
JVM類加載是JVM利用類加載器將class文件加載到JVM的過程,涉及“加載”、“驗證”、“”準備“、“”解析“和”初始化“。
一、類的成員變量初始化 ---在JVM類加載階段完成
類的成員變量又分爲靜態成員變量和非靜態成員變量。
靜態成員變量
靜態成員變量會被初始化兩次,第一次在“準備”階段,先進行一次初始化,系統附上默認值;第二次在“初始化”階段,根據代碼中的賦值情況再進行一次初始化。
例如:
public static int i =3 ;
第一次初始化後i的值爲0,第二次初始化後,值才爲3.
數據最終存放在方法區中。
非靜態成員變量
僅“初始化”階段賦值。根據代碼中的賦值情況,代碼不賦值直接賦默認值,有賦值則等於代碼中的賦值。對象實例化後,該變量隨java對象分配到java堆中。
二、方法區的局部變量沒有初始化
而方法中的局部變量沒有初始化步驟,如下圖:
需要在代碼中進行初始化。
原因就是類方法中的代碼,實在字節碼執行的時候,纔會被運行到,此時局部變量是存儲在虛擬機棧-棧幀中的局部變量表中。局部變量定義了但是沒有賦值是不能使用的。