创建类的一个实例时,按照下面步骤进行创建:
1. 给当前类及其父、祖类的所有成员字段分配空间,并给它们赋予默认值
2. 开始执行当前类的构造器
3. 如果当前类有父类,则对父类创建一个实例:从第 2 步开始并把父类当作新的当前类
4. 给当前实例、当前实例的字段进行初始化
5. 执行当前类的构造器的剩余部分代码。
上面的步骤包含一个递归算法。假设类 C 有父类,实例化 C 到第 3 步的时候,需要先创建父类的一个实例,即父类要经历完第 2、3、4、5 步骤之后,才到类 C 继续第 4 步。如果父类也有自己的父类,则父类的父类也要先实例化,才到父类执行第 3 步。依次类推,直到实例化 Object 类,因为 Object 类没有父类。
下面有两个例子进行说明。
例子1
public class Point { int x, y; Point(){ x = 1; y = 1; } }
public class ColoredPoint extends Point { int color = 0xFF00FF; }
public class InstanceDemo { public static void main(){ ColoredPoint cp = new ColoredPoint(); System.out.println(cp.x + " | " + cp.y + " | " + cp.color); } }
引起创建类的实例的是代码 new ColoredPoint(),下面是实例创建的步骤:
1. 分配内存给字段 x, y, color, 并给他们赋予默认值
2. ColoredPoint 的构造器被调用
3. ColoredPoint 没有声明构造器,则调用其默认构造器:
ColoredPoint(){ super(); }
4. 上面的 super() 实际指的是 Point 的无参构造器。Point 的无参构造器最开始部分没有调用其他构造器,则 Java 编辑器提供插入了一个构造器调用,变成:
Point(){ super(); x = 1; y = 1; }
5. 上面的 super() 实际指的是 Object 的无参构造器。Object 没有父类,不会被插入构造器。Object 的无参构造器没有任何副作用或返回值。被调用的构造器如下
Object() { }
6. Point 的字段被初始化。在这里,字段 x, y 无需被初始化。
7. Point 的构造器被继续执行,即对 x , y 分别赋值为 1 。至此,父类 Point 实例化结束
8. ColoredPoint 的字段被初始化。在这里,字段 color 被初始化为 0xFF00FF。
9. ColoredPoint 的构造器被继续执行。在这里,没有其他代码在构造器里面,无需继续执行。至此,ColoredPoint 实例化结束。
( 例子2 待续..
参考资料
12.5 Creation of New Class Instance, The Java Language Specification, Java SE 8 Edition