publicclassStaticInitialization { publicstaticvoidmain(String[] args) { System.out.println("Creating class B in main..."); Bb1=newB(); }
staticBb2=newB();
/* * Initial class A with 2 * Initial class A with 3 * Initial class A with 1 * Initial class B * This is A.f() * Creating class B in main... * Initial class A with 1 * Initial class B * This is A.f() */ }
classA { A(int value) { System.out.println("Initial class A with " + value); }
voidf() { System.out.println("This is A.f()"); } }
classB { Aa1=newA(1); staticAa2=newA(2);
B() { System.out.println("Initial class B"); a2.f(); }
staticAa3=newA(3); }
静态字段 a2 和 a3 的创建在 a1 字段之前,且仅在第一个 B 对象创建时被初始化,之后这些静态对象不会被重新初始化。
因此初始化的顺序是从静态字段开始,然后是非静态字段。例如要执行静态的 main 方法,必须先加载 StaticInitialization 类,然后初始化他的静态字段 b2,这就导致类 B 被加载,而类 B 中包含静态的类 A 的对象,因此 A 也被加载,所以这个程序中所有的类都在 main 方法开始执行前被加载。
现在总结一下对象创建的过程,假设有一个名为 A 的类:
尽管没有显式使用 static 关键字,但构造器实际上也是静态方法。因此,第一次创建类型为 A 的对象时,或者第一次访问类 A 的静态方法或静态字段时,Java 解释器会搜索类路径来定位 A.class 文件。
当 A.class 被加载后(这将创建一个 Class 对象),它的所有静态初始化工作都会执行。因此,静态初始化只在 Class 对象首次加载时发生一次。
当使用 new A() 创建对象时,构建过程首先会在堆上为 A 对象分配足够的存储空间。
这块存储空间会被淸空,然后自动将该 A 对象中的所有基本类型设置为其默认值(数值类型的默认值是0,boolean 和 char 则是和0等价的对应值),而引用会被设置为 null。