1、類的加載、連接和初始化
- JVM和類
同一個JVM的所有線程、所有變量都處於同一個進程裏,它們都使用該JVM進程的內存區
當系統出現一下集中情況時,JVM進程將被終止:
程序運行到最後正常結束
程序運行到使用Sytem.exit()或Runtime.getRuntime().exit()代碼處結束程序
程序執行過程中遇到未捕獲的異常或錯誤而結束
程序所在平臺強制結束JVM進程
當JVM進程結束時,該進程在內存中的狀態將會丟失
- 類加載(當程序主動使用某個類,將類的class文件讀入內存,併爲之創建一個java.lang.Class對象)
從本地class文件加載
從JAR加載clas文件
網絡加載class文件
動態編譯Java源文件並執行加載
- 類的連接
驗證:驗證語法是否正確
準備:爲靜態屬性分配內存及設置默認值
解析:將類的二進制數據中的符號引用替換成直接引用???
- 類的初始化(靜態屬性初始化)
聲明靜態屬性時指定初始值
使用靜態初始化塊爲靜態屬性指定初始值
- 類的初始化時機
new一個實例、反射創建實例、反序列化創建實例
調用某個類的靜態方法
訪問某個類或接口的靜態屬性,或爲靜態屬性賦值
反射創建某個類或接口的java.lang.Class對象
初始化某個類的子類、孫類等
直接使用java.exe運行某個主類
注意:final型靜態屬性,如果編譯時就有屬性值則是常量,被調用時,該類不會被初始化。如果是運行時編譯的,被調用時,該類會初始化,如:
static final String time = System.currentTimeMillis() + “”;
精妙例子:http://www.jb51.net/article/86629.htm
- 類加載器
Bootstrap ClassLoader:根類加載器
Extension ClassLoader:擴展類加載器
System ClassLoader:系統類加載器
ClassLoader loader = TestClassLoader.class.getClassLoader()
// sun.misc.Launcher$AppClassLoader@500c05c2 System.out.println(loader.toString())
// sun.misc.Launcher$ExtClassLoader@454e2c9c System.out.println(loader.getParent().toString())
// null System.out.println(loader.getParent().getParent())
2、反射
- 對象運行的類型:
編譯時類型
運行時類型(需要用反射來調用)
- 作用
假如我們有兩個程序員,一個程序員在寫程序的時候,需要使用第二個程序員所寫的類,但第二個程序員並沒完成他所寫的類。那麼第一個程序員的代碼能否通過編譯呢?這是不能通過編譯的。利用Java反射的機制,就可以讓第一個程序員在沒有得到第二個程序員所寫的類的時候,來完成自身代碼的編譯。
- 獲取
- 如果編寫代碼的時候,就知道Class的名字,可以直接用如下方式得到Class對象:
Class exampleObjectClass = ExampleObject.class;
- 如果在編寫代碼的時候,不知道類的名字,但是在運行時的時候,可以得到一個類名的字符串,可以用如下的方式獲取Class對象:
Class exampleObjectClass = Class.forName("cn.byhieg.reflectiontutorial.ExampleObject");