《think in java 4 》笔记系列三——Java中各种成员变量初始化顺序

构造器初始化顺序

public class Tag {
    Tag(int marker) {
        System.out.println("Tag(" + marker + ")");
    }
}

public class Card {
    Card() {
        // Indicate we're in the constructor:
        System.out.println("Card()");
        t3 = new Tag(33); // Re-initialize t3
    }
    Tag t1 = new Tag(1); // Before constructor

    Tag t3 = new Tag(3); // At end
    Tag t2 = new Tag(2); // After constructor

    void f() {
        System.out.println("f()");
    }

}

public class OrderOfInitialization {
    public static void main(String[] args) {
        Card t = new Card();
        t.f(); // Shows that construction is done
    }
}

输出结果

Tag(1)
Tag(3)
Tag(2)
Card()
Tag(33)
f()

结论

  1. 首先自上而下初始化当前类中其他成员变量构造器
  2. 再初始化当前类的构造器

继承关系的构造器初始化顺序

public class Meal {
    Meal() {
        System.out.println("Meal()");
    }
}

class Lunch extends Meal {
    Lunch() {
        System.out.println("Lunch()");
    }
}

class PortableLunch extends Lunch {
    PortableLunch() {
        System.out.println("PortableLunch()");
    }
}

public class Bread {
    Bread() {
        System.out.println("Bread()");
    }
}

public class Cheese {
    Cheese() {
        System.out.println("Cheese()");
    }
}

public class Lettuce {
    Lettuce() {
        System.out.println("Lettuce()");
    }
}

class Sandwich extends PortableLunch {
    Bread b = new Bread();
    
    Sandwich() {
        System.out.println("Sandwich()");
    }
    Cheese c = new Cheese();
    Lettuce l = new Lettuce();

    public static void main(String[] args) {
        new Sandwich();
    }
} 

运行结果

Meal()
Lunch()
PortableLunch()
Bread()
Cheese()
Lettuce()
Sandwich()

结论

构造器的初始化顺序
1.先从当前类的最顶层父类依次而下初始化父类构造器
2.然后初始化成员变量构造器
3.最后是当前类的构造器


静态构造器初始化顺序

基本类型static变量初始化时,如果没有赋值,会自动获得自己的标准基本类型初始值。
引用类型static变量初始化时,如果已经创建了一个对象,则指向该对象的引用地址,否则就默认是null

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

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

public class Table {
    static Bowl b1 = new Bowl(1);
    Table() {
        System.out.println("Table()");
        b2.f(1);
    }

    void f2(int marker) {
        System.out.println("f2(" + marker + ")");
    }

    static Bowl b2 = new Bowl(2);
}

public class Cupboard {
    Bowl b3 = new Bowl(3);
    static Bowl b4 = new Bowl(4);

    Cupboard() {
        System.out.println("Cupboard()");
        b4.f(2);
    }

    void f3(int marker) {
        System.out.println("f3(" + marker + ")");
    }

    static Bowl b5 = new Bowl(5);
}

public class StaticInitialization {
    static Table t2 = new Table();
    static Cupboard t3 = new Cupboard();

    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();
        t2.f2(1);
        t3.f3(1);
    }

}

运行结果

Bowl(1)
Bowl(2)
Table()
f(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f(2)
f2(1)
f3(1)

结论

  1. 首先按照从上到下的顺序初始化类中的static成员变量,并且只在第一次创建该类的时候初始化一次
  2. 然后按照从上到下的顺序初始化类中的普通成员变量,每次创建改类的实例时,都会初始化成员比变量

子父类间构造器初始化顺序

public class Insect {
    int i = 9;
    int j;

    Insect() {
        prt("i = " + i + ", j = " + j);
        j = 39;
    }

    static int x1 = prt("static Insect.x1 initialized");

    static int prt(String s) {
        System.out.println(s);
        return 47;
    }
}

public class Beetle extends Insect {
    int k = prt("Beetle.k initialized");

    Beetle() {
        prt("k = " + k);
        prt("j = " + j);
    }

    static int x2 = prt("static Beetle.x2 initialized");

    static int prt(String s) {
        System.out.println(s);
        return 63;
    }

    public static void main(String[] args) {
        prt("Beetle constructor");
        Beetle b = new Beetle();
    }
    int s = prt("Beetle.s initialized");
}

运行结果

static Insect.x1 initialized
static Beetle.x2 initialized
Beetle constructor
i = 9, j = 0
Beetle.k initialized
Beetle.s initialized
k = 63
j = 39

得出结论

  1. 初始化父类static属性
  2. 初始化子类static属性
  3. 初始化父类属性,自上而下
  4. 初始化父类构造器
  5. 初始化子类属性,自上而下
  6. 初始化子类构造器

你可能感兴趣的:(《think in java 4 》笔记系列三——Java中各种成员变量初始化顺序)