1.初始化顺序
在类的内部,变量定义的先后顺序决定了初始化的顺序,即时变量散布于方法定义之间,它们仍就会在任何方法(包括构造器)被调用之前得到初始化。
1 class Window { 2 Window(int maker) { 3 System.out.println("Window(" + maker + ")"); 4 } 5 } 6 7 class House { 8 Window window1 = new Window(1); 9 10 House() { 11 System.out.println("House()"); 12 w3 = new Window(33); 13 } 14 15 Window window2 = new Window(2); 16 17 void f() { 18 System.out.println("f()"); 19 } 20 21 Window w3 = new Window(3); 22 23 } 24 25 public class OrderOfInitialization { 26 public static void main(String[] args) { 27 House h = new House(); 28 h.f(); 29 } 30 }
Window(1) Window(2) Window(3) House() Window(33) f()
由输出可见,w3这个引用会被初始化两次:一次在调用构造器之前,一次在调用期间(第一次引用的对象将被丢弃,并作为垃圾回收)。
2.静态数据的初始化
无论创建多少个对象,静态数据都只占一份存储区域。static关键字不能应用于局部变量,因此它只能作用于域。
1 class Bowl { 2 Bowl(int maker) { 3 System.out.println("Bowl(" + maker + ")"); 4 } 5 6 void f1(int maker) { 7 System.out.println("f1(" + maker + ")"); 8 } 9 } 10 11 class Table { 12 static Bowl bowl1 = new Bowl(1); 13 14 Table() { 15 System.out.println("Table()"); 16 bowl2.f1(1); 17 } 18 19 void f2(int maker) { 20 System.out.println("f2(" + maker + ")"); 21 } 22 23 static Bowl bowl2 = new Bowl(2); 24 } 25 26 class Cupboard { 27 Bowl bowl3 = new Bowl(3); 28 static Bowl bowl4 = new Bowl(4); 29 30 Cupboard() { 31 System.out.println("CupBoard()"); 32 bowl4.f1(2); 33 } 34 35 void f3(int maker) { 36 System.out.println("f3(" + maker + ")"); 37 } 38 39 static Bowl bowl5 = new Bowl(5); 40 } 41 42 public class StaticInitialization { 43 public static void main(String[] args) { 44 System.out.println("created new Cupboard() in main"); 45 new Cupboard(); 46 System.out.println("created new Cupboard in main"); 47 new Cupboard(); 48 table.f2(1); 49 cupboard.f3(1); 50 } 51 52 static Table table = new Table(); 53 static Cupboard cupboard = new Cupboard(); 54 }
Bowl(1) Bowl(2) Table() f1(1) Bowl(4) Bowl(5) Bowl(3) CupBoard() f1(2) created new Cupboard() in main Bowl(3) CupBoard() f1(2) created new Cupboard in main Bowl(3) CupBoard() f1(2) f2(1) f3(1)
由输出可见,静态初始化只有在必要时刻才会进行。如果不创建Table对象,也不引用Table.b1或Table.b2,那么静态的Bowl b1和b2永远都不会被创建。只有在第一个Table对象被创建(或者第一次访问静态数据)的时候,他们才会被初始化。此后,静态对象不会再次被初始化。
3.非静态实例初始化
实例初始化子句在两个构造器之前执行。
1 class Mug { 2 Mug(int maker) { 3 System.out.println("Mug(" + maker + ")"); 4 } 5 6 void f(int maker) { 7 System.out.println("f(" + maker + ")"); 8 } 9 } 10 11 public class Mugs { 12 Mug mug1; 13 Mug mug2; 14 { 15 mug1 = new Mug(1); 16 mug2 = new Mug(2); 17 System.out.println("mug1 & mug2 initialized"); 18 } 19 20 Mugs() { 21 System.out.println("Mugs()"); 22 } 23 24 Mugs(int maker) { 25 System.out.println("Mugs(int)"); 26 } 27 28 public static void main(String[] args) { 29 System.out.println("Inside main()"); 30 new Mugs(); 31 System.out.println("new Mugs() complete"); 32 new Mugs(1); 33 System.out.println("new Mugs(1) complete"); 34 } 35 }
Inside main() Mug(1) Mug(2) mug1 & mug2 initialized Mugs() new Mugs() complete Mug(1) Mug(2) mug1 & mug2 initialized Mugs(int) new Mugs(1) complete