本文摘录于http://blog.csdn.net/socoolfj/archive/2006/05/23/750425.aspx,并修改例子的代码,加上自己的见解。
类装载步骤 在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,其中链接又可以分成校验、准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的,各个步骤的主要工作如下: 装载:查找和导入类或接口的二进制数据; 链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的; 校验:检查导入类或接口的二进制数据的正确性; 准备:给类的静态变量分配并初始化存储空间; 解析:将符号引用转成直接引用; 初始化:激活类的静态变量的初始化Java代码和静态Java代码块。 其中 初始化(initialization)包含两部分: 1.类的初始化(initialization class & interface) 2.对象的创建(creation of new class instances)。 因为类的初始化其实是类加载(loading of classes)的最后一步,所以很多书中把它归结为“对象的创建”的第一步。其实只是看问题的角度不同而已。为了更清楚的理解,这里还是分开来。 顺序: 因为类的加载肯定是第一步的,所以类的初始化在前。大体的初始化顺序是: 类初始化 -> 子类构造函数 -> 父类构造函数 -> 实例化成员变量 -> 继续执行子类构造函数的语句 下面结合例子,具体解释一下。 1. 类的初始化(Initialization classes and interfaces) 其实很简单,具体来说有: (a)初始化类(initialization of class),是指初始化static field 和执行static初始化块。 - public class Demo{
- //初始化static field,
- //其中= "initialization static field"又叫做static field initializer
- private static String str = "initialization static field";
-
- //初始化块,又叫做static initializer,或 static initialization block
- static {
- System.out.println("This is static initializer");
- }
- }
btw,有些书上提到static initializer 和 static field initializer 的概念,与之对应的还有 instance initializer 和 instance variable initializer。例子中的注释已经解释了其含义。 (b)初始化接口(initialization of interface),是指初始化定义在该interface中的field。 *注意* 1. initialization classes 时,该class的superclass 将首先被初始化,但其实现的interface则不会。 initialization classes 时,该class的superclass,以及superlcass的superclass 会首先被递归地初始化,一直到java.lang.Object为止。但initialiazation interface的时候,却不需如此,只会初始化该interface本身。 2. 对于由引用类变量(class field)所引发的初始化,只会初始化真正定义该field的class。 3. 如果一个static field是编译时常量(compile-time constant),则对它的引用不会引起定义它的类的初始化。 为了帮助理解最后两点,请试试看下面的例子:
|