初始化顺序
在类中变量定义的顺序决定了它们初始化的顺序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class House { Window w1 = new Window(1);
House(){ System.out.println("House()"); Window window = new Window(11); }
Window w2 = new Window(2);
void f(){ System.out.println("f()"); }
Window w3 = new Window(3);
public static void main(String[] args) { House house = new House(); house.f(); } }
public class Window { public Window(int mark){ System.out.println("Window("+mark+")"); } }
|
执行结果
1 2 3 4 5 6
| Window(1) Window(2) Window(3) House() Window(11) f()
|
验证类加载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| public class Initable { public static final int COUNT =new Random().nextInt(1000); static { System.out.println("Initable初始化"); } }
public class Initable1 { public static final int COUNT = 47;
static { System.out.println("Initable1初始化"); } }
public class Initable2 { public static int COUNT = 56;
static { System.out.println("Initable2初始化"); } }
public class Initable3 { public static int COUNT = 33;
static { System.out.println("Initable3初始化"); } }
public class Initable4 { public static int COUNT = 44;
static { System.out.println("Initable4初始化"); } }
结果: Initable--------------- Initable初始化 457 Initable1--------------- 47 Initable2--------------- Initable2初始化 56 Initable3--------------- Initable4--------------- Initable4初始化
|
对于static final的值是一个编译期常量的话(如Initable1.COUNT),获取这个值时不需要对Initable1进行初始化就可以读取,如果用static final的值不是一个编译期常量(如Initable.COUNT),访问这个变量会强制对该类进行初始化
对于一个仅仅是static修饰的字段而不是final的,在读取这个字段之前,需要为该字段分配存储空间以及初始化该存储空间
使用.class语法不会对类进行初始化,而使用Class.forName()来产生Class引用会直接引发类的初始化
注意:如果没有显式的编写构造器的话,java编译器会默认提供一个无参构造器,但是如果提供了自己的构造器,编译器将不会再生成默认构造器。