2015-06-28 2 views
4

Я знаю, что статические блоки инициализируются во время загрузки класса и, поскольку класс загружается только один раз в программу, они инициализируются только один раз.Почему блоки инициализации экземпляра выполняются перед конструкторами

IIB (блоки инициализации экземпляра) инициализируются каждый раз, когда экземпляр класса создается, и тот же для конструкторов: они выполняются во время создания объекта.

Я не понимаю, почему в приведенной ниже программе IIB выполняется перед конструкторами.

код-
public class Hello { 

    public static void main(String args[]) { 
     C obj = new C(); 
    } 
} 

class A { 

    static { 
     System.out.println("Inside static block of A"); 
    } 

    { 
     System.out.println("Inside IIB of A"); 
    } 

    A() { 
     System.out.println("Inside NO-ARGS constructor of A"); 
    } 
} 

class B extends A { 

    static { 
     System.out.println("Inside static block of B"); 
    } 

    { 
     System.out.println("Inside IIB of B"); 
    } 

    B() { 
     System.out.println("Inside NO-ARGS constructor of B"); 
    } 
} 
class C extends B { 

    static { 
     System.out.println("Inside static block of C"); 
    } 

    { 
     System.out.println("Inside IIB of C"); 
    } 

    C() { 
     System.out.println("Inside NO-ARGS constructor of C"); 
    } 
} 

Почему IIB выполняется первым по сравнению с конструкторами?

+5

На самом деле конструкторы называют первым, но ваш 'sysout' выполняется после того, как блок инициализации, который вставляется в качестве первого оператора (после 'super()') компилятором. https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html –

ответ

5

Компилятор Java вводит блоки инициализатора at the beginning of your constructors (после вызова суперконструктора). Чтобы дать вам лучше понять, я составил следующий класс

public class Foo extends SuperFoo { 
    private String foo1 = "hello"; 
    private String foo2; 
    private String foo3; 
    { 
     foo2 = "world"; 
    } 
    public Foo() { 
     foo3 = "!!!"; 
    } 
} 

и запустить его через javap декомпилятором:

Compiled from "Foo.java" 
public class Foo extends SuperFoo { 
    private java.lang.String foo1; 
    private java.lang.String foo2; 
    private java.lang.String foo3; 
    public Foo(); 
    Code: 
     0: aload_0 
     1: invokespecial #12     // Method SuperFoo."<init>":()V 
     4: aload_0 
     5: ldc   #14     // String hello 
     7: putfield  #16     // Field foo1:Ljava/lang/String; 
     10: aload_0 
     11: ldc   #18     // String world 
     13: putfield  #20     // Field foo2:Ljava/lang/String; 
     16: aload_0 
     17: ldc   #22     // String !!! 
     19: putfield  #24     // Field foo3:Ljava/lang/String; 
     22: return 
}