【问题标题】:Why are instance initialization blocks executed before constructors为什么实例初始化块在构造函数之前执行
【发布时间】:2015-09-15 01:21:09
【问题描述】:

我知道静态块是在加载类时初始化的,因为类在程序中只加载一次,所以它们只初始化一次。

每次创建类的实例时都会初始化 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?

【问题讨论】:

标签: java constructor initialization


【解决方案1】:

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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-08
    • 1970-01-01
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多