Java Class類與反射機制學習筆記(一)
阿新 • • 發佈:2018-12-13
類的載入
當一個程式使用某一個類時,如果該類還未被載入到記憶體中,則系統會通過載入、連線、初始化三個步驟來實現對這個類的初始化。
- 載入 就是指將該類的 .class檔案讀入記憶體中,併為之建立一個Class物件(java.lang.class物件 )。這個Class物件就是用來表示 .class檔案內容的東西。(.class檔案內容一般包括成員變數、構造方法、成員方法),任何類被使用時,系統都會建立一個Class物件。
- 連線驗證 是否有正確的內部結構,並和其他類協調一致準備 負責為類的靜態成員分配記憶體,並設定預設初始值(靜態是隨著類的載入而載入的,靜態內部類只有在被呼叫時,才會被載入
執行結果:public class Test { static { System.out.println("外部類的輸出。"); } //靜態內部類 static class StaticInner { static { System.out.println("內部類的輸出。"); } static void staticInnerMethod() { System.out.println("內部靜態方法的輸出。"); } } public static void main(String[] args) { Test outer = new Test(); //這裡內部類不會被載入 System.out.println("------------------分割線------------------"); Test.StaticInner.staticInnerMethod(); //呼叫內部類的靜態方法 } }
- 初始化 類的初始化階段,虛擬機器負責對類進行初始化,主要就是對類變數進行初始化(包括靜態屬性、靜態初始化塊)。類初始化之前,先要進行父類初始化, 因為子類可能會用到父類的東西)。在Java類中對類變數指定初始值有兩種方式: 方式一:宣告類變數時指定初始值; 方式二:使用靜態初始化塊為類變數指定初始值。在一個類中,如果希望先執行類的初始化動作,可以使用static定義一個靜態區域。當這個類被使用時,首先執行static塊中的程式,並且只會執行一次。
class Example_A{ public static int a = 1;//宣告變數時指定初始值 public static int b;//預設值 public static String str1 = "Hello";//宣告變數時指定初始值 public static String str2;//預設值 public Example_A(){ a = 9; System.out.println("\n建構函式中\n a的值:" + a); System.out.println("b的值:" + b); System.out.println("str1的值:" + str1); System.out.println("str2的值:" + str2); } static{//靜態域 System.out.println("執行靜態域中的內容:"); System.out.println("靜態域中未改變前, a的值"+ a); a = 5; System.out.println("靜態域中改變後, a的值"+a); } } public class Test { public static void main(String[] args){ Example_A e1 = new Example_A(); System.out.println("---------------分割線---------------"); Example_A e2 = new Example_A(); } }
執行結果:srh fbcx
分析:從執行結果我們可以看出,Example_A物件的初始化,首先執行的是static域中的內容,並且這個域只被執行一次。
類的載入時機
- 建立類的例項
- 訪問類的靜態變數,或者為靜態變數賦值
- 呼叫類的靜態方法
- 使用反射方式來強制建立某個類或介面對應的 java.lang.Class 物件
- 直接使用java .exe(*)命令來執行某個主類
類的載入器
負責將 .class檔案載入到記憶體中,併為之生成對應的Class物件。
組成:Bootstrap ClassLoader 根類載入器(引導類載入器),負責Java核心類的載入,比如JDK中JRE的lib目錄下rt,jar檔案System,String等。
Extension ClasLoader 擴充套件類載入器,負責JRE的擴充套件目錄中jar包的載入,在JDK中JRE的lib目錄下ext目錄。
System ClassLoader 系統類載入器,負責在JVM啟動時載入來自java命令的class檔案,以及classpath環境變數所指定的jar包和類路徑。
java反射
Java反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制, 在java.lang.reflect包中提供了對該功能的支援。要想解剖一個類,必須先要獲取到該類的位元組碼檔案物件。而解剖使用的就是Class類中的方法.所以先要獲取到每一個位元組碼檔案對應的Class型別的物件.
三種獲取Class物件的方式
- ObjectName obj = new ObjectName(); Class c = obj.getClass();
- Class c = ObjectName.class; //任意資料型別都具備一個class靜態屬性
- 將類名作為字串傳遞給Class類中的靜態方法forName即可,可通過配置檔案配置載入,擴充套件性強 Class c = Class.forName("ObjectPath");