2016-02-02 40 views
24

Napisałem poniższy kod i utworzony obiekt dla super klasy.Dlaczego kod statyczny podkategorii jest wykonywany?

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

Po sprawdzeniu wyjście, to jest w następujący sposób:

super 
sub 
Super 
2 
2 

wiem, że blok statyczny jest wykonywana tylko wtedy, gdy obiekt klasy jest inicjowany lub dowolny statyczny odesłania. Ale tutaj, nie zrobiłem żadnego z nich do klasy Sub. to dlaczego widzę "statyczną" blokową wydajność "pod", czyli podklasę?

+11

Wykonywanie metody 'main' (zagnieżdżonej w klasie' Sub') jest statycznym odwołaniem. :) –

+0

@KonstantinYovkov Myślałem o tym, ale nawet wtedy "sub" powinien być na pierwszym miejscu. Teraz ta wątpliwość została usunięta z odpowiedzi Bathsheby, ponieważ statyczne bloki są wykonywane w kolejności super i podklas. Dziękuję Ci. – AV94

+3

@anil nie pierwszy, klasa 'Sub' nadal zależy od klasy' Super', która jest w związku z tym wykonywana jako pierwsza. – njzk2

Odpowiedz

37

Wiem, że blok statyczny jest wykonywany tylko po zainicjowaniu obiektu klasy lub wykonaniu jakiegokolwiek odniesienia statycznego. Ale tutaj, nie zrobiłem żadnego z nich do klasy Sub.

Kod nie robi, ale w porządku dla tego main do uruchomienia, Sub musi być załadowany. Więc inicjalizator statyczny jest uruchamiany.

przykład jestem zakładając, że prowadził ją tak:

java Sub 

Narzędzie java musi załadować Sub zadzwonić Sub.main. To jest odniesienie statyczne (dostęp, naprawdę), powodując uruchomienie inicjalizatora statycznego. (Jeśli uruchomiłeś go w IDE, IDE wykona część narzędzia java, ale wynik będzie taki sam.)

Więc oto co się stało:

  1. java wyzwala ładunek Sub

  2. JVM musi załadować SuperClass w celu załadowania Sub

  3. Widzimy więc ich statyczne inicjalizatory biegać, w kolejności (SuperClass, następnie Sub):

    super 
    sub 
    
  4. java narzędzie nazywa main

  5. kod w main połączeń new SuperClass:

    Super 
    
  6. kod w main połączeń f.c()

    2 
    
  7. kod w main połączenia SuperClass.b:

    2 
    

jako Holger pomocny points out, jest objęte niniejszym opisie JVM §5.5 - Initialization i podobne §5.2 - Java Virtual Machine Startup:

inicjalizacji klasy lub interfejs składa się z wykonania klasę lub metoda inicjalizacji interfejsu (§2.9).

klasy lub interfejs C może być inicjowane tylko w wyniku:

  • ...

  • Jeśli C jest klasa inicjalizacja jednego z jego podklasy.

  • Jeśli C jest klasą, jej oznaczenie jako klasy początkowej podczas uruchamiania wirtualnej maszyny Java (§5.2).

To drugi do ostatni podpunkt obejmuje SuperClass, a ostatni podpunkt obejmuje Sub.

12

Ponieważ twoja metoda main() jest członkiem Sub, ta klasa musi zostać załadowana, aby twój program działał.

9

Podczas wywoływania main wszystkie statyczne inicjatory są wywoływane, najpierw w super klasie, a następnie w podklasie.

To wyjaśnia wynik, który obserwujesz.

3

bloki statyczne są uruchamiane po załadowaniu klasy. zwykle dlatego, że wywołujesz konstruktora lub statyczny element. w tym przypadku dzieje się tak, ponieważ wykonano główną metodę (statyczny element).

boczne Uwagi:

  1. inny przypadek kant dzwoni Class.forName (className) załadowanie klasy.
  2. możesz również zauważyć, że klasa podstawowa jest ładowana przed podklasą.