2016-11-20 4 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(); 
    } 
} 

だからあなたはもう、それはあなたのsuperクラスコードを壊すかもしれない、あなたのフィールドaを初期化することはできません。

finalメソッドをオーバーライドすることはできません。したがって、フィールドaを初期化することができ、superクラスのものはすべて破棄されません。

あなたの疑いが明確になることを願っています。次のように

+0

があなたの記事を読んで、私は疑問を持ってきたあなたの答えsincerely.Iいただきありがとうございます。私たちはのコンストラクタを呼び出す前に、サブクラスのnon_fieldが初期化されますそのサブクラスは正しいのですか?それで、なぜnon_fieldをコンストラクタから呼び出せないのですか?私はそれを理解していません。 – Manhand

+0

私は非常に残念ですが、私は間違った質問をタイプします。質問はコンストラクタから非最終メソッドを呼び出さないでください(私はあなたの記事を読んでいますが、質問があります:サブクラスのnon_fieldは私たちがサブクラスのコンストラクタを呼び出す前に初期化されていましたか?そうではありません。なぜ、コンストラクタからfinalではないメソッドを呼び出すことができませんか?私はそれを理解しません) – Manhand

+0

@Manhandあなたのコンストラクタで非最終メソッドを呼び出すことはお勧めしません。それを確認してください。 – SkrewEverything

1

シーケンスは次のとおりです。

  1. あなたはJVMがStaticTestsをロードjava StaticTests

  2. を入力します。

  3. JVMは、static void main(String[])メソッドを探して呼び出しを試みます。

  4. main(...)を呼び出すと、静的な初期化がStaticTestsになります。 (クラスは静的メソッドへの最初の呼び出しの前に初期化されます。)

  5. StaticTestsの静的初期化は、StaticSuperの静的初期化をトリガします。クラスが初期化される前に、クラスのスーパークラスを初期化する必要があります。

  6. "super static block"はスーパースタティックinitによって出力されます。

  7. 「静的ブロック4」は、サブクラスstatic initによって印刷されます。

  8. main(...)コールが開始されます。

  9. System.out.println("in main")ステートメントが実行され、「主に」印刷されます。

  10. new StaticTestsは、StaticTestsコンストラクタを呼び出します。

  11. StaticTestsコンストラクタは、暗黙的にsuper()を呼び出します。 (通常のJavaの動作)

  12. スーパークラスのコンストラクタは "スーパーコンストラクタ"を出力します。

  13. サブクラスのコンストラクタ版画「コンストラクタ」

+0

静的メソッドの前に静的フィールドを初期化する場合は、誠実に答えていただきありがとうございますか? – Manhand

+0

静的フィールドは、クラスの静的初期化の一部として初期化されます。あ、はい。 –