5.7 构造器的初始化顺序

构造器初始化流程顺序 主要是包括这几层关系:

      非静态成员属性、静态成员属性、非静态代码块、静态代码块、构造器,这5者的关系.

对于这几层关系 ,我分开来阐述,避免在一个类中统一归纳,比较麻烦,不易理解。

1.非静态成员属性

     可以看到w1、w2、w3 散列于House()构造方法之间,但从结果来看,是先初始化w1,w2,w3,最后调用构造方法

package com.caolh._5InitializationAcleanup;//: initialization/_5_7OrderOfInitialization.java
// Demonstrates initialization order.


// When the constructor is called to create a
// Window object, you'll see a message:
class Window {
  Window(int marker) { System.out.println("Window(" + marker + ")"); }
}

class House {
  Window w1 = new Window(1); // w1在构造器之前调用
  House() {
    // Show that we're in the constructor:
    System.out.println("House()");
    w3 = new Window(33); // Reinitialize w3
  }
  Window w2 = new Window(2); // w1在构造器之后调用
  void f() { System.out.println("f()"); }
  Window w3 = new Window(3); // At end
}

public class _5_7OrderOfInitialization {
  public static void main(String[] args) {
    
    House h = new House();
    h.f(); // Shows that construction is done
  }
} /* Output:
Window(1)
Window(2)
Window(3)
House()
Window(33)
f()
*///:~

2.引入静态成员属性,初始化过程

看测试结果:记住几个原则:

只是静态属性的引用,是触发的类加载此时不执行构造方法,类加载只执行一次,这些值存在于常量池;而创建对象,是也可以触发类加载的(如果之前没有,那么会首先执行静态属性初始化),这些值存在于堆栈,而且此时才会执行构造器方法

1.先执行 静态的成员属性初始化,再执行非静态成员属性初始化。

2.静态成员属性初始化只执行1次,就是在调用该类的静态属性或静态方法,或者是第一次创建对象的时候;以后多次创建,不执行静态属性初始化了

package com.caolh._5InitializationAcleanup;//: initialization/StaticInitialization.java
// Specifying initial values in a class definition.

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("Creating new Cupboard() in main");
    new Cupboard();
    System.out.println("Creating new Cupboard() in main");
    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)
----------------------
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
------------------------
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
--------------------------
f2(1)
f3(1)
*///:~

3.引入静态代码块

 static 的cup1 定义和静态代码块先后顺序无所谓,

只执行(1),直接触发静态代码块。

只执行(2),两次创建对象,静态代码块只执行1次

package com.caolh._5InitializationAcleanup;//: initialization/ExplicitStatic.java
// Explicit static initialization with the "static" clause.


class Cup {
  Cup(int marker) {
    System.out.println("Cup(" + marker + ")");
  }
  void f(int marker) {
    System.out.println("f(" + marker + ")");
  }
}

class Cups {
  static Cup cup1;
  static {
    cup1 = new Cup(1);
    cup2 = new Cup(2);
  }
  static Cup cup2;
  Cups() {
    System.out.println("Cups()");
  }
}

public class ExplicitStatic {
  public static void main(String[] args) {
    System.out.println("Inside main()");
    //Cups.cup1.f(99);  // (1)
  }
  static Cups cups1 = new Cups();  // (2)
  static Cups cups2 = new Cups();  // (2)
} /* Output:
Cup(1)
Cup(2)
Cups()
Cups()
Inside main()
*///:~

4.非静态代码块引入

可以看到,对象创建2次,非静态代码块执行了2次

package com.caolh._5InitializationAcleanup;//: initialization/_5_7_4Mugs.java
// Java "Instance Initialization."


class Mug {
  Mug(int marker) {
    System.out.println("Mug(" + marker + ")");
  }
  void f(int marker) {
    System.out.println("f(" + marker + ")");
  }
}

public class _5_7_4Mugs {
  Mug mug1;
  Mug mug2;
  {
    mug1 = new Mug(1);
    mug2 = new Mug(2);
    System.out.println("mug1 & mug2 initialized");
  }
  _5_7_4Mugs() {
    System.out.println("Mugs()");
  }
  _5_7_4Mugs(int i) {
    System.out.println("Mugs(int)");
  }
  public static void main(String[] args) {
    System.out.println("Inside main()");
    new _5_7_4Mugs();
    System.out.println("new Mugs() completed");
    new _5_7_4Mugs(1);
    System.out.println("new Mugs(1) completed");
  }
} /* Output:
Inside main()
Mug(1)
Mug(2)
mug1 & mug2 initialized
Mugs()
new Mugs() completed
Mug(1)
Mug(2)
mug1 & mug2 initialized
Mugs(int)
new Mugs(1) completed
*///:~

 

 

 

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页