1. 程式人生 > >Java Class類與反射機制學習筆記(一)

Java Class類與反射機制學習筆記(一)

類的載入

當一個程式使用某一個類時,如果該類還未被載入到記憶體中,則系統會通過載入、連線、初始化三個步驟來實現對這個類的初始化。

  • 載入 就是指將該類的 .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域中的內容,並且這個域只被執行一次。

類的載入時機

  1. 建立類的例項
  2. 訪問類的靜態變數,或者為靜態變數賦值
  3. 呼叫類的靜態方法
  4. 使用反射方式來強制建立某個類或介面對應的 java.lang.Class 物件
  5. 直接使用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物件的方式

  1. ObjectName obj = new ObjectName(); Class c = obj.getClass();
  2. Class c = ObjectName.class; //任意資料型別都具備一個class靜態屬性
  3. 將類名作為字串傳遞給Class類中的靜態方法forName即可,可通過配置檔案配置載入,擴充套件性強 Class c = Class.forName("ObjectPath");