Thinking in Java(2)
1.构造器初始化
1.1 初始化顺序
无法阻止自动初始化的进行,自动初始化发生在构造器被调用之前。
在类的内部,变量定义先后顺序决定了初始化顺序。即使变量定义散布于方法定义之间,它们也会在任何方法被调用之前初始化。
import java.util.*;
class Window {
Window(int marker) {
System.out.println("Windows("+marker+")");
}
}
class House {
Window w1 = new Window(1);
House() {
System.out.println("House");
w3 = new Window(33);
}
void f() {
System.out.println("f()");
}
Window w2 = new Window(2);
Window w3 = new Window(3);
}
public class OrderOfInitialization {
public static void main(String[] args) {
House h = new House();
h.f();
}
}
//result:
//Windows(1)
//Windows(2)
//Windows(3)
//House
//Windows(33)
//f()
可以看出先初始化类内成员变量再调用构造函数初始化。
1.2 静态数据的初始化
初始化顺序是先静态对象再非静态对象,且静态初始化只有在必要(创建对象或者访问静态方法静态域)时刻才会进行。
import java.util.*;
class Bowl {
Bowl(int i) {
System.out.println("Bowl("+i+")");
}
}
public class StaticInitialization {
Bowl b1 = new Bowl(1);
static Bowl b2 = new Bowl(2);
static Bowl b3 = new Bowl(3);
public static void main(String[] args) {
new StaticInitialization();
}
}
//result
//Bowl(2)
//Bowl(3)
//Bowl(1)
1.3 显式静态初始化
将多个静态初始化动作组织成一个特殊的静态子句
import java.util.*;
class Cup {
Cup(int i) {
System.out.println("Cup("+i+")");
}
}
public class ExplicitStatic {
Cup cups3 = new Cup(3);
static Cup cups1;
static Cup cups2;
//静态块
static {
cups1 = new Cup(1);
cups2 = new Cup(2);
}
public static void main(String[] args) {
new ExplicitStatic();
}
}
//result
//Cup(1)
//Cup(2)
//Cup(3)
1.4非静态实例初始化
类似于静态块, 非静态实例也可以进行同样的初始化
import java.util.*;
class Cup {
Cup(int i) {
System.out.println("Cup("+i+")");
}
}
public class Normal {
Cup c1;
Cup c2;
{
c1 = new Cup(1);
c2 = new Cup(2);
}
static Cup c3 = new Cup(3);
public static void main(String[] args) {
new Normal();
}
}
//result
//Cup(3)
//Cup(1)
//Cup(2)
1.5 总结
通过上面的例子,我们可以得出在创建类对象的时候先初始化静态实例,然后再初始化非静态实例,静态初始化只有在必要(创建对象或者访问静态方法静态域)时刻才会进行。