1. 程式人生 > >《瘋狂Java講義》學習筆記(十四)類載入機制與反射

《瘋狂Java講義》學習筆記(十四)類載入機制與反射

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@454
e2c9c 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");