class檔案的載入、初始化、例項化
阿新 • • 發佈:2018-12-02
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物件了