java 类加载生命周期_Java类的加载与生命周期
一、概要:
類的生命周期從類的 加載、連接、初始化 開始,到類的 卸載結束;
二、幾個階段:
加載:查找并加載類的二進制數據。(把類的.class文件的二進制數據讀入內存,存放在運行時數據區的方法區;類加載的最終結果是產生堆區中描述對應類的Class對象);
連接:包括驗證、準備和解析三個子階段;
驗證:確保補加載類的正確性;
準備:為類的靜態變量分配內存,并設定默認值;
解析:把類中的符號引用轉換為直接引用;
初始化:給類中的靜態變量賦予正確的初始值;
類的加載時機:并不需要等到某個類被主動使用時才加載,虛擬機會預測某個類將要被使用就加載它;
類的初始化時機:
a. 創建類(new、反射、克隆、反序列化)
b. 使用靜態方法、非靜態變量
c. Class.forName("ATest"); ?獲取描述類的Class對象;
另:初始化子類,父類被先初始化。虛擬機的啟動類,使用命令 java Sample(也算是創建類);
注:
使用能在編譯期能得知的final static修飾的常量,不會導致類的初始化;
public static final int a = 2*3;//編譯時常量,不會導致類初始化;
public static final int a b = (int)(Math.random()*10)/10+1; // 不是編譯時常量,會初始化;
只有當程序訪問的靜態變量或靜態方法的確在當前類或接口中定義時,才可以看作是對類或接口的主動使用;(如用子類引用調用父類靜態方法或變量,只會初始化父類)
調用ClassLoader.loadClass()方法加載一個類時,只會加載,但不會初始化;
子類父類初始化過程:
先對這個類進行加載和連接-> 如果有直接父類,先加載連接初始化這個父類->重復以上步驟直到所有父類初始化,初始化當前類;
(先加載連接當前類,再加載連接初始化父類,再初始化當前類)
classBase {static{
System.out.println("init Base");
}
}class Sub extendsBase {static{
System.out.println("init Sub");
}
}public class ATest extendsSub {static{
System.out.println("init ATest");
}public static voidmain(String args[]) {
System.out.println("main methos");
}
}
結果:
init Base
init Sub
init ATest
main methos
View Code
三、類加載器
除了Java虛擬機自帶的根類加載器以外,其余的類加載器有且只有一個父加載器;
Java虛擬機自帶以下幾種加載器:
根(Bootstrap)類加載器:沒有父類加載器。負責加載虛擬機核心類,sun.boot.class.path路徑下類庫,java.lang.*; 實現依賴于底層操作系統,沒有繼承java.lang.ClassLoader;
擴展(Extension)類加載器:父加載器為根加載器;加載java.ext.dirs下的類庫 和 JDK目錄下jre/lib/ext目錄下類庫;繼承于java.lang.ClassLoader;
系統(System)類加載器:也稱應用類加載器,父加載器為擴展類加載器;加載classpath路徑下指定的類庫;繼承于java.lang.ClassLoader,也是自定義加載器的默認父類;
父親委托機制:
類加載過程中,會先從最頂層加載器(一般是根加載器)開始往下,先判斷父類加載器能不能加載,能加載則往下傳遞返回加載的類;不能加載則繼續往下判斷,如果都不能加載,則會拋出ClassNotFoundException異常;
加載器之間的父子關系實際上是指加載器對象之間的包裝關系,而不是類之間的繼承關系;
命名空間:
命名空間由該加載器及所有父加載器所加載的類組成;
唯一性:在同一個命名空間中,不會出現類的完整名字(包名+類名)相同的兩個類;
同一命名空間有以下關系:
同一命名空間的類是相互可見的;(可見是指可以直接使用其類名,不可見的類之間可以通過反射來獲取類信息);
子加載器的命名空間所含所有父加載器的命名空間,所有子類加載器的類能看見父加載器的類;但父加載器不能看見子加載器的類;
運行時包:
包名相同,且屬于同一個類加載器;
同一運行時包的類才能包可見;如用戶自己定義了一個java.lang.Spy,并由自己定義的類加載器加載,由于java.lang.Spy和核心類庫java.lang.*由不同的類加載器加載,它們不在同一運行時包,Spy不能訪問java.lang.*下的包可見類;
用戶自定義類加載器:
擴展java.lang.ClassLoader類,然后覆蓋它的findClass(String name)方法;
可通過 this.getClass().getClassLoader()獲取類對應的加載器
類的卸載:(清除對應類的Class對象 和 類的二進制數據結構)
由Java虛擬自帶的三個類加載器加載的類不能卸載;(虛擬機會始終引用這3個類加載器,類加載器中有一個集合,又會一直引用其加載的類的Class對象)
用戶自定義的類加載器加載的類可以被卸載;
整理自孫衛琴《Java面象對象編程》
總結
以上是生活随笔為你收集整理的java 类加载生命周期_Java类的加载与生命周期的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android studio导入ecli
- 下一篇: java 线程状态_面试官问:为什么Ja