首頁 >Java >java教程 >Java中類別的載入順序剖析(常用於面試題)

Java中類別的載入順序剖析(常用於面試題)

高洛峰
高洛峰原創
2017-01-13 09:24:451388瀏覽

這其實是去年校招時我遇到的一道阿里巴巴的筆試題(承認有點久遠了-。-),嗯,如果我沒記錯的話,當時是作為Java方向的一道選做大題。當然題意沒有這麼直白,題目只要求你寫出程式執行後所有System.out.println的輸出結果,其中程式是題目給的,而各個System.out.println的執行順序不同會導致最後程式輸出的結果也不同。

具體的題目我肯定記不清,不過我們可以換個直接的問法,如果類A和類B中有靜態變量,靜態語句塊,非靜態變量,非靜態語句塊,構造函數,靜態方法,非靜態方法,同時類A繼承類B,請問當實例化A時,類內部的加載順序是什麼?

當時我也是一頭霧水,事後我就自己寫了一個小Demo,這才知道了類內部的實際載入順,測試程式碼如下:

Class B:

public class B{
//静态变量  
static int i=1;
//静态语句块
static {
    System.out.println("Class B1:static blocks"+i);
}
//非静态变量
int j=1;
//静态语句块
static{
    i++;
    System.out.println("Class B2:static blocks"+i);
}
//构造函数
public B(){
    i++;
    j++;
    System.out.println("constructor B: "+"i="+i+",j="+j);
}
//非静态语句块
{
  i++;
  j++;
  System.out.println("Class B:common blocks"+"i="+i+",j="+j);
}
//非静态方法
public void bDisplay(){
    i++;
    System.out.println("Class B:static void bDisplay(): "+"i="+i+",j="+j);
    return ;
}
//静态方法
public static void bTest(){
    i++;
    System.out.println("Class B:static void bTest():    "+"i="+i);
    return ;
}
}

Class A:

public class A extends B{
//静态变量  
static int i=1;
//静态语句块
static {
    System.out.println("Class A1:static blocks"+i);
}
//非静态变量
int j=1;
//静态语句块
static{
    i++;
    System.out.println("Class A2:static blocks"+i);
}
//构造函数
public A(){
    super();
    i++;
    j++;
    System.out.println("constructor A: "+"i="+i+",j="+j);
}
//非静态语句块
{
  i++;
  j++;
  System.out.println("Class A:common blocks"+"i="+i+",j="+j);
}
//非静态方法
public void aDisplay(){
    i++;
    System.out.println("Class A:static void aDisplay(): "+"i="+i+",j="+j);
    return ;
}
//静态方法
public static void aTest(){
    i++;
    System.out.println("Class A:static void aTest():    "+"i="+i);
    return ;
}
}

Class ClassLoading :

public class ClassLoading {
     
    public static void main (String args[]) {
        A a=new A();
        a.aDisplay();
    }
}

程式運作結果如圖:

Java中類別的載入順序剖析(常用於面試題)

的看出java類別的整個載入過程。

1.若要載入類別A,則先載入執行其父類別B(Object)的靜態變數以及靜態語句區塊(執行先後順序按排列的先後順序)。

2.然後再載入執行類別A的靜態變數以及靜態語句塊。 (且1、2步驟只會執行1次)
3.若需實例化類別A,則先呼叫其父類別B的建構子,並且在呼叫其父類別B的建構子前,依序先呼叫父類B中的非靜態變數及非靜態語句區塊.最後再呼叫父類別B中的建構子初始化。
4.然後再依序呼叫類別A中的非靜態變數及非靜態語句塊.最後呼叫A中的建構子初始化。 ( 並且3、4步驟可以重複執行)
5.而對於靜態方法和非靜態方法都是被動調用,即係統不會自動調用執行,所以用戶沒有調用時都不執行,主要區別在於靜態方法可以直接用類別名稱直接呼叫(實例化物件也可以),而非靜態方法只能先實例化物件後才能呼叫。

OK,今天就總結到這裡了,如果有地方說的不好或有錯誤的地方,歡迎大家指出,定當改正,謝謝。

更多Java中類別的載入順序剖析(常用於面試題)相關文章請關注PHP中文網!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn