1. 程式人生 > >class檔案的載入、初始化、例項化

class檔案的載入、初始化、例項化

class檔案的載入包含以下過程:載入(load class檔案)-校驗-準備-解析-初始化-例項化,上述過程是大致過程,具體過程可以參考:jvm class檔案載入過程

看下面的程式碼樣例:

package staticclass;

public class StaticClassTest {
    public static void main(String[] args) throws ClassNotFoundException {
        ClassLoader.getSystemClassLoader().loadClass("staticclass.User"
); System.out.println("====="); Class.forName("staticclass.User"); System.out.println("+++++"); } } //展示class檔案的載入 class User{ public static int age=27; private String name; static{ System.out.println("this is static age="+age); } { System.out
.println(" age ="+age); } public User(String name){ System.out.println("this is constructor age="+age); this.name=name; } public void print(){ System.out.println("this is "+name); } public static void printAge(){ System.out.println("this is static printAge age="
+age); } } 輸出內容: ===== this is static age=27 +++++ 從輸出內容看到:ClasLoader把class檔案進行載入,只是把相關的class檔案載入到了方法區,進行了解析,並沒有進行初始化,而Class.forName除了上述步驟執行了相關的初始化。

把StaticClassTest 的main方法修改如下:

public static void main(String[] args) throws ClassNotFoundException {
        Class.forName("staticclass.User");
        System.out.println("+++++");
        User u = new User("jkf");
    }

輸出內容:
this is static age=27
+++++
 age =27
this is constructor age=27


從輸出內容來看:Class.forName進行了初始化,而new User進行了例項化,但是static程式碼塊,僅執行了一次,並且程式碼塊的執行優先建構函式。

把StaticClassTest 的main方法修改如下:

public static void main(String[] args) throws ClassNotFoundException {
        int age = User.age;
        System.out.println("----------");
        User u = new User("jkf");
    }
輸出內容:
this is static age=27
----------
 age =27
this is constructor age=27

從輸出內容看:當我們呼叫類的靜態屬性或者方法時,僅進行了類的初始化,並不會進行例項化。

綜上所述:
1 class檔案的載入可以通過:ClassLoader進行載入。
2 class檔案的初始化:Class.forName;呼叫類檔案的靜態方法或靜態屬性。
3 class檔案的例項化:通過new;或者通過Class物件的newInstance()方法。
4 當然class檔案的初始化包含了class檔案的載入,同樣class檔案的例項化也包含上述兩個步驟。
5 說一個有關陣列的問題:

package com.classLoader;

/**class物件的載入時機**/
public class ClassLoaderTime {
    public static void main(String[] args) {
        ClassLoader[] arr = new ClassLoader[4];
        System.out.println("陣列賦值");
        arr[0]=new ClassLoader();
    }
}

class ClassLoader{
    static{
        System.out.println("物件初始化");
    }
}

輸出內容:
陣列賦值
物件初始化

從輸出內容來看,物件陣列建立時,並沒有載入初始化物件,而是在陣列手動賦值時進行載入初始化,這是因為我們new物件了