构造方法

  • 字段初始化:字段初始化是在对象创建时,即在构造函数之前执行的。
  • 从上到下的顺序进行初始化
  • 可以直接使用常量对成员变量进行初始化
  • 也可以使用函数进行初始化

    • 注意如果函数有参数则参数必须是已经初始化的
  • 实例初始化块:实例初始化块是在对象创建时,在字段初始化之后但在构造函数之前执行的。

  • 静态初始化块会优先执行,只能初始化静态变量,在类初次加载时执行(创建对象/访问静态成员)
  • 普通初始化块按顺序执行,实例化时执行
    class A{
        // 静态初始化块
        static {
            System.out.println("static init block A");
        }
        // 普通初始化块
        {
            System.out.println("common init block A");
        }
        // 构造方法
        public A() {
            System.out.println("Constructor without params A");
        }
    }
    

^0710ee - 初始化顺序

class Bowl {
  Bowl(int marker) {
    System.out.println("Bowl(" + marker + ")");
  }
  void f1(int marker) {
    System.out.println("f1(" + marker + ")");
  }
}

class Table {
  static Bowl bowl1 = new Bowl(1);
  Table() {
    System.out.println("Table()");
    bowl2.f1(1);
  }
  void f2(int marker) {
    System.out.println("f2(" + marker + ")");
  }
  static Bowl bowl2 = new Bowl(2);
}

class Cupboard {
  Bowl bowl3 = new Bowl(3);
  static Bowl bowl4 = new Bowl(4);
  Cupboard() {
    System.out.println("Cupboard()");
    bowl4.f1(2);
  }
  void f3(int marker) {
    System.out.println("f3(" + marker + ")");
  }
  static Bowl bowl5 = new Bowl(5);
}

public class StaticInitialization {
  public static void main(String [] args) {
    System.out.println("main creating new Cupboard()");
    new Cupboard();
    System.out.println("main creating new Cupboard()");
    new Cupboard();
    table.f2(1);
    cupboard.f3(1);
  }
  static Table table = new Table();
  static Cupboard cupboard = new Cupboard();
}
/* Output:
Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
main creating new Cupboard()
Bowl(3)
Cupboard()
f1(2)
main creating new Cupboard()
Bowl(3)
Cupboard()
f1(2)
f2(1)
f3(1)
*/

  • 静态字段的初始化:首先,类TableCupboard的静态字段在首次被访问时初始化。在StaticInitializationmain方法执行之前,会初始化这两个类的静态字段,因为它们在main方法中被用作静态字段。(初始类之前要先对其的静态成员进行初始化)
  • Table.bowl1初始化,打印Bowl(1)
  • Table.bowl2初始化,打印Bowl(2)
  • Cupboard.bowl4初始化,打印Bowl(4)
  • Cupboard.bowl5初始化,打印Bowl(5)

  • TableCupboard的实例初始化:之后,StaticInitialization中的静态字段tablecupboard被初始化。

  • 当初始化table时:
    • 调用Table的构造函数,打印Table()
    • 在构造函数中调用bowl2.f1(1),打印f1(1)
  • 当初始化cupboard时:

    • Cupboard.bowl3初始化,打印Bowl(3)(这是一个实例字段,所以在每次创建Cupboard实例时都会初始化)。
    • 调用Cupboard的构造函数,打印Cupboard()
    • 在构造函数中调用bowl4.f1(2),打印f1(2)
  • 执行main方法

  • 打印main creating new Cupboard()
  • 创建新的Cupboard实例:
    • Cupboard.bowl3初始化,打印Bowl(3)
    • 调用Cupboard的构造函数,打印Cupboard()
    • 在构造函数中调用bowl4.f1(2),打印f1(2)
  • 打印main creating new Cupboard()
  • 再次创建新的Cupboard实例:
    • Cupboard.bowl3初始化,打印Bowl(3)
    • 调用Cupboard的构造函数,打印Cupboard()
    • 在构造函数中调用bowl4.f1(2),打印f1(2)
  • 调用table.f2(1),打印f2(1)
  • 调用cupboard.f3(1),打印`f3(1)

  • 在构造函数中调用构造函数

  • this(目标构造函数参数)
  • 只能在构造函数中调用

  • 存在继承的构造

  • 默认只会调用父类的无参构造函数,如果需要有参构造函数需要显式调用super(xx)
  • 父类->成员(按照声明顺序进行初始化)->自身
    public class Test {
        public static void main(String [] args) {
            new SubClass();
        }
    }
    class SuperClass {
        static int staticSuperVar = initStaticSuperVar();
        int instanceSuperVar = initInstanceSuperVar();
    
        static {
            System.out.println("Static initializer of SuperClass");
        }
    
        {
            System.out.println("Instance initializer of SuperClass");
        }
    
        SuperClass() {
            System.out.println("Constructor of SuperClass");
        }
    
        static int initStaticSuperVar() {
            System.out.println("Static variable of SuperClass");
            return 0;
        }
    
        int initInstanceSuperVar() {
            System.out.println("Instance variable of SuperClass");
            return 0;
        }
    }
    
    class SubClass extends SuperClass {
        static int staticSubVar = initStaticSubVar();
        int instanceSubVar = initInstanceSubVar();
    
        static {
            System.out.println("Static initializer of SubClass");
        }
    
        {
            System.out.println("Instance initializer of SubClass");
        }
    
        SubClass() {
            System.out.println("Constructor of SubClass");
        }
    
        static int initStaticSubVar() {
            System.out.println("Static variable of SubClass");
            return 0;
        }
    
        int initInstanceSubVar() {
            System.out.println("Instance variable of SubClass");
            return 0;
        }
    }
    /*
    Static variable of SuperClass
    Static initializer of SuperClass
    Static variable of SubClass
    Static initializer of SubClass
    Instance variable of SuperClass
    Instance initializer of SuperClass
    Constructor of SuperClass
    Instance variable of SubClass
    Instance initializer of SubClass
    Constructor of SubClass
    */