2016-02-02 3 views
24

次のコードを記述し、スーパークラスのオブジェクトを作成しました。サブクラスの静的コードが実行されるのはなぜですか?

class SuperClass{ 
    static int a=2; 
    static int b(){ 
     return 2; 
    } 
    int c(){ 
     return 2; 
    } 

    SuperClass(){ 
     System.out.println("Super"); 
    } 
    static { 
     System.out.println("super"); 
    } 
} 

public class Sub extends SuperClass{ 
    Sub(){ 
    System.out.println("Sub"); 
    } 
    static { 
     System.out.println("sub"); 
    } 
    static int b(){ 
     return 3; 
    } 
    int c(){ 
     return 3; 
    } 
    public static void main(String ax[]){ 
     SuperClass f =new SuperClass(); 
     System.out.println(f.c()); 
     System.out.print(SuperClass.b()); 
    } 
} 

Iが出力をオンにすると、以下のように、それは:

super 
sub 
Super 
2 
2 

Iは、クラスのオブジェクトが初期化されるか、または任意の静的参照が行われた場合にのみ静的ブロックが実行されていることを知っています。しかし、ここでは、私はこれらのいずれかをSubクラスにしませんでした。それではなぜ「サブ」すなわちサブクラスの静的ブロック出力が表示されるのですか?

+11

'main'メソッド(' Sub'クラスにネストされています)を実行することは静的な参照です。 :) –

+0

@ ConstantinYovkov私はそれについて考えましたが、それでも "サブ"が最初に正しく来るはずです。さて、その疑問は、静的ブロックがスーパークラスとサブクラスの順番で実行されるため、バテシバの答えからクリアされます。ありがとうございました。 – AV94

+3

@anilまず、 'Sub'クラスはまだ' Super'クラスに依存しています。このクラスは最初に実行されます。 – njzk2

答えて

37

静的ブロックは、クラスのオブジェクトが初期化されたとき、または静的参照が行われたときにのみ実行されることがわかります。しかし、ここでは、私はこれらのいずれかをSubクラスにしませんでした。

あなたコードはしていませんが、それmainを実行するためには、Subをロードする必要があります。そのために、静的イニシャライザが実行されます。

例えば、私はあなたがこのようにそれを実行したと仮定しています:

java Sub 

javaツールはSub.mainを呼び出すためにSubをロードする必要があります。それは静的な初期化子を実行させる静的な参照(アクセス)です。 (IDEで実行した場合、IDEはjavaツール部分を実行しますが、結果は同じです。だからここ)

は何が起こったのです。

  1. javaは、JVMは、だから我々は彼らの静的初期化子が実行見るSub

  2. をロードするためにSuperClassをロードする必要がありSub

  3. の負荷をトリガし、順番に(SuperClass、次にSub):

    通話0でf.c()

    2 
    
  4. コードで

    Super 
    
  5. コード:

    super 
    sub 
    
  6. javaツールはmain呼び出しnew SuperClassにコードmain

  7. を呼び出しますはSuperClass.bを呼び出し:

    2 
    

、これは§5.5 - Initializationと関連§5.2 - Java Virtual Machine StartupでJVM仕様によって覆われpoints out親切Holgerとおり

クラスまたはインタフェースの初期化は、そのクラスの実行から成りまたはインタフェースの初期化方法(§2.9)。

クラスまたはインタフェースCのみの結果として初期化されてもよい

  • ...

  • Cは、そのサブクラスの1つの初期化クラスである場合。

  • Cがクラスである場合、Java仮想マシンの起動(§5.2)での初期クラスとしてのその指定。最後から2番目の箇条書きがSuperClassを覆い、最後の箇条書きがSubを覆う

12

main()メソッドのメンバーがSubであるため、プログラムを実行するにはそのクラスをロードする必要があります。

9

mainを呼び出すと、すべての静的初期化子が最初にスーパークラスで呼び出され、次にサブクラスが呼び出されます。

これは、あなたが観察する出力を説明しています。

3

クラスがロードされるときにスタティックブロックが実行されます。通常はコンストラクタまたは静的メンバーを呼び出すためです。この場合は、メインメソッド(静的メンバー)を実行したためです。

サイドノート:

  1. 別のエッジケースは、クラスをロードするようにClass.forName(クラス名)を呼び出しています。
  2. サブクラスの前に基本クラスが読み込まれていることに気付くかもしれません。
関連する問題