如果在一个构造器的内部调用正在构造的的对象的某个动态绑定的方法,会发生什么情况?
我们来看一个例子:
class Glyph{ public void draw() { System.out.println("Glyph draw"); } Glyph() { System.out.println("Glyph before draw"); draw(); //调用动态绑定的方法 System.out.println("Glyph after draw"); } } class RoundGlyph extends Glyph{ private int radius = 1; public RoundGlyph(int i) { this.radius = i; System.out.println("RoundGlyph radius = " + this.radius); } public void draw() { System.out.println("RoundGlyph draw radius = " + this.radius); } } public class Garbage{ public static void main(String[] args) { new RoundGlyph(2); } } 输出: Glyph before draw RoundGlyph draw radius = 0 Glyph after draw RoundGlyph radius = 2
我们会看到,如果调用构造器内部的动态绑定的方法的话,就要用到那个方法被覆盖后的定义。 这一点是没错的。可是我们看到radius却与我们想象的不同。
要解释这个首要理清在继承关系中的初始化过程:
1:类加载时首先检查类中的静态变量,然后初始化静态变量,静态变量总是在类加载之前完成。 (注意这里静态变量的初始化也是按继承成层次不断往上的)
参考例子:http://www.cnblogs.com/E-star/archive/2013/04/06/3002862.html
2:加载类,分配内存空间,分配给对象的存储空间被初始化为二进制的零
3:依次调用构造函数。
4:按照声明顺序调用成员的初始化方法
所以我们在基类的构造方法里面调用还未完成初始化的radius的时候他的默认值为0;
参考Java编程思想P164