构造器内部初始化实际过程
类初始化顺序
类的初始化遵循的顺序很多人都知道是这样:
(1)调用基类构造器,不断重复这个过程直到最底层
(2)再按照声明的顺序调用成员的初始化方法
(3)调用类构造器的主体
类初始化的实际过程
但是,考虑这样一个例子:
1 |
|
Animal类的walk方法被设计为在Cat类中被重写,但是Animal的构造器会调用这个walk方法,这导致了对Cat.walk()的调用。
上述代码的生成结果是:
Animal() before walk()
Cat.walk(), step = 0
Animal() after walk()
Cat.Cat(), step = 500
我们会发现当Animal的构造器调用walk()方法的时候,step不是默认的初始值100,而是0。
因此前面讲的类初始化的顺序并不完整,实际上类的初始化顺序应该是这样的:
(1)在所有事情发生之前先分配空间,将分配给对象的存储空间初始化成二进制的零(或者某些特殊数据类型中与零等价的值)
(2)如前所述的调用基类构造器,这个时候在调用cat构造器之前就要调用walk方法,因此此时的step值是0
(3)按照声明的顺序调用成员的初始化方法
(4)调用类构造器的主体
当然,这种错误并不容易发现,因此推荐大家如果可以的话,构造器中尽可能避免调用其他方法,在构造器内唯一能够安全调用的那些方法是基类的final方法(因为他们不会被重写,也就不会有上述的问题)。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hongjin's Blog!
评论