2016-02-02 5 views
24

Ich habe den folgenden Code geschrieben und ein Objekt für die Superklasse erstellt.Warum wird der statische Code der Subklasse ausgeführt?

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()); 
    } 
} 

Wenn ich die Ausgabe geprüft, es ist wie folgt:

super 
sub 
Super 
2 
2 

Ich weiß, dass statischer Block nur dann ausgeführt wird, wenn das Objekt der Klasse initialisiert wird, oder ein statischer Bezug genommen wird. Aber hier habe ich keine der Sub-Klassen gemacht. Warum sehe ich dann "sub", d. h. die statische Blockausgabe der Unterklasse?

+11

Das Ausführen der 'main'-Methode (die in der 'Sub'-Klasse verschachtelt ist) ist eine statische Referenz. :) –

+0

@KonstantinYovkov Ich dachte darüber nach, aber selbst dann "sub" sollte zuerst richtig kommen. Dieser Zweifel wird nun aus Bathshebas Antwort geklärt, da statische Blöcke in der Reihenfolge Super- und Unterklassen ausgeführt werden. Vielen Dank. – AV94

+3

@anil nicht zuerst, die 'Sub'-Klasse hängt immer noch von der' Super'-Klasse ab, die daher zuerst ausgeführt wird. – njzk2

Antwort

37

Ich weiß, dass statische Block nur ausgeführt wird, wenn Objekt der Klasse initialisiert oder eine statische Referenz ist. Aber hier habe ich keine der Sub-Klassen gemacht.

Ihr Code nicht der Fall, sondern um für diese main zu laufen, hat Sub geladen werden. Also wird der statische Initialisierer dafür ausgeführt.

Z. B. Ich gehe davon aus Sie es wie folgt lauten:

java Sub 

Das java Werkzeug hat Sub zu laden Sub.main zu nennen. Das ist die statische Referenz (wirklich der Zugriff), die bewirkt, dass der statische Initialisierer ausgeführt wird. (Wenn Sie es in einer IDE ausführen, wird die IDE den java Tool-Teil tun, aber das Ergebnis ist das gleiche.)

Also hier ist, was passiert ist:

  1. java löst Last von Sub

  2. JVM SuperClass, um zu laden hat Sub

  3. So laden wir ihre statische Initialisierer sehen laufen, in Reihenfolge (SuperClass, dann Sub):

    super 
    sub 
    
  4. java Tool ruft main

  5. -Code in main Anrufe new SuperClass:

    Super 
    
  6. -Code in main Anrufe f.c()

    2 
    
  7. -Code in main Anrufe SuperClass.b:

    Initialisierung einer Klasse oder Schnittstelle besteht seine Klasse ausführt:

    2 
    

Als Holger helfend points out dies durch die JVM-Spezifikation in §5.5 - Initialization und die damit verbundenen §5.2 - Java Virtual Machine Startup bedeckt ist oder Interface-Initialisierungsmethode (§2.9).

  • ...

  • Wenn C eine Klasse ist, die eine Initialisierung von ihren Unterklassen:

    A-Klasse oder Schnittstelle C kann nur als Ergebnis initialisiert werden.

  • Wenn C ist eine Klasse, seine Bezeichnung als Ausgangsklasse an Java Virtual Machine Start (§ 5.2).

dass Second-zu-letzten Aufzählungspunkt umfasst SuperClass und der letzte Aufzählungspunkt umfasst Sub.

12

Da Ihre main()-Methode ein Mitglied von Sub ist, muss diese Klasse geladen werden, damit Ihr Programm ausgeführt werden kann.

9

Beim Aufrufen von main werden alle statischen Initialisierer aufgerufen, zuerst in der Superklasse und dann in der Unterklasse.

, dass die Ausgabe, die Sie beobachten, erklärt.

3

statische Blöcke werden ausgeführt, wenn die Klasse geladen wird. Normalerweise rufen Sie einen Konstruktor oder ein statisches Member auf. in diesem Fall ist es, weil Sie die Hauptmethode (ein statisches Element) ausgeführt.

Seiten Anmerkungen:

  1. andere Kante Fall Class.forName (classname) Aufruf einer Klasse zu laden.
  2. Sie können auch feststellen, dass die Basisklasse vor der Unterklasse geladen wird.