2016-11-20 89 views
-1

我在網上搜索了很長時間。但沒用。請幫助或嘗試提供一些想法如何實現此目的?爲什麼結果不是在第一個打印「int main」?我想知道的是爲什麼這個程序的結果如下?預先感謝。靜態方法的執行順序(JAVA)

超靜塊

靜塊4

在主

超級構造

構造

class StaticSuper { 
     static { 
      System.out.println("super static block"); 
     } 


     StaticSuper() { 
      System.out.println("super constructor");  
     } 
    } 

    public class StaticTests extends StaticSuper { 
     static int rand; 

     //static initialise 
     static {   
     rand = (int) (Math.random() * 6); 
     System.out.println("static block " + rand);  
     } 

     StaticTests() { 
      System.out.println("constructor"); 
     } 

     public static void main(String[] args) { 
      System.out.println("in main"); 
      StaticTests st = new StaticTests(); 
     } 
    } 

回答

1

點火次序是:

  1. 父的靜止象素塊和字段中出現的順序
  2. 兒童的靜止象素塊和字段,以便外觀
  3. 父非靜態字段初始
  4. 父構造

  5. 兒童非靜電場初始化器

  6. 兒童構造函數

你可以閱讀更多關於here


更新:

運行這一點,你就會明白,爲什麼你不應該調用父類的構造函數非final方法。

public class Derived extends Super 

{ 

    @Override 
    void initialise() 
    { 
     System.out.println("Now you can't initialise field \"a\" anymore"); 
    } 
    Derived() 
    { 

    } 
    public static void main(String[] args) 
    { 
     Derived d = new Derived(); 

    } 
} 

class Super 
{ 
    private int a; 
    void initialise() 
    { 
     a = 10; 
    } 
    Super() 
    { 
     initialise(); 
    } 
} 

所以你不能初始化你的領域a了它可能會破壞你的super類代碼。

final方法不能被覆蓋。因此,您可以初始化a字段,並且不會破壞super課程中的任何內容。

我希望它能澄清你的疑問。

+0

謝謝您的回答sincerely.I已經看了你的文章,我有一個問題:我們所說的構造函數之前子類的non_field初始化子類,是不是?我們爲什麼不能從構造函數中調用non_field?我不理解它。 – Manhand

+0

我對此感到很抱歉,我輸入的問題是錯誤的。問題是爲什麼我們不應該從構造函數中調用非final方法(。我已經閱讀過您的文章,並且有一個問題:子類的non_field是在我們調用子類的構造函數之前進行初始化,是不是?我們爲什麼不能從構造函數中調用非final方法?我不明白) – Manhand

+0

@Manhand我用代碼更新了我的答案,以解釋爲什麼它不建議在構造函數中調用非final方法。覈實。 – SkrewEverything

1

的順序如下:

  1. 您鍵入java StaticTests

  2. 的JVM加載StaticTests

  3. JVM找到static void main(String[])方法並嘗試調用它。

  4. main(...)的調用觸發了StaticTests的靜態初始化。 (一個類在第一次調用靜態方法之前被初始化。)

  5. StaticTests的靜態初始化觸發了StaticSuper的靜態初始化。 (在類初始化之前,必須初始化一個類的超類。)

  6. 「超級靜態塊」由超靜態初始化打印。

  7. 「靜態塊4」由子類static init打印。

  8. main(...)通話開始。

  9. 執行System.out.println("in main")語句,打印「in main」。

  10. new StaticTests調用構造函數StaticTests

  11. StaticTests構造函數隱式調用super()。 (普通的Java行爲)

  12. 超類構造函數打印「超級構造函數」。

  13. 子類構造函數打印「構造」

+0

謝謝你的回答,如果靜態方法之前靜態字段將被初始化? – Manhand

+0

靜態字段被初始化爲類靜態初始化的一部分。所以是的。 –