三种初始化数据域的方法:
- 在构造器中设置值
- 在声明中赋值
- 初始化块(initialization block)
初始化块
在一个类的声明中,可以包含多个代码块。只要构造类的对象,这些块就会被执行。
class Employee {
private static int nextId;
private int id;
private String name;
private double salary;
// object initialization block
{
id = nextId;
nextId++;
}
}
在上面这个示例中,无论使用哪个构造器构造对象,id 域都在对象初始化块中被初始化。首先运行初始化块,然后才运行构造器的主体部分。
初始化块这种机制不是必需的,也不常见。通常会直接将初始化代码放在构造器中。
由于初始化数据域有多种途径,所以列出构造过程的所有路径可能相当混乱。下面是调用构造器的具体处理步骤:
- 所有数据域被初始化为默认值(0、false 或 null)
- 按照在类声明中出现的次序,依次执行所有域初始化语句和初始化块
- 如果构造器第一行调用了第二个构造器,则执行第二个构造器主体
- 执行这个构造器的主体
静态的初始化块
可以通过提供一个初始化值,或者使用一个静态的初始化块来对静态域进行初始化。
前面已经介绍过第一种机制(提供一个初始化值):private static int nextId = 1;
如果对类的静态域进行初始化的代码比较复杂,那么可以使用静态的初始化块。将代码放在一个块中,并标记关键字 static。下面是一个示例。其功能是将雇员 ID 的起始值赋予一个小于 10000 的随机整数。
// static initialization block
static {
Random generator = new Random();
nextId = generator.nextInt(lOOOO);
}
在类第一次加载的时候,将会进行静态域的初始化。与实例域一样,除非将它们显式地设置成其他值,否则默认的初始值是 0、false 或 null。所有的静态初始化语句以及静态初始化块都将依照类定义的顺序执行。
参考资料
《Java核心技术卷一:基础知识》(第10版)第 4 章:对象与类 4.6.7 初始化块