Picses' sky

Picses' sky
posts - 43, comments - 29, trackbacks - 0, articles - 24

也谈一个对象初始化细节

Posted on 2007-12-20 10:46 Matthew Chen 阅读(1067) 评论(1)  编辑  收藏 所属分类: Java SE
网上这类的文章多了,也就归纳了一下:

初始化按串行顺序如下:

……
超类静态成员变量
超类静态块
子类静态成员变量
子类静态块
……

……
超类成员变量分配引用并默认初始化
子类成员变量分配引用并默认初始化
……
……
超类成员变量用显式初始化值赋值
超类构造器
子类成员变量用显式初始化值赋值
子类构造器
……
……


另外,这样的初始化顺序中,如果子类继承了超类的a方法并在其中修改了子类自己的成员变量,而a方法在超类的构造函数中被调用,那么这个修改的值将被“子类成员变量用显式初始化值赋值”这一过程重新覆盖而导致修改失效。

我是这样理解的,大家给点意见。


Feedback

# re: 也谈一个对象初始化细节  回复  更多评论   

2007-12-20 14:53 by 隔叶黄莺
记住以下两点就好理解了

类的成员先于实例成员初始化
父类实例与子类实例的关系可以理解为 Is-A 的关系

所以子类实例初始化之前必须先有父类的实例

其实还应该区分类的初始化和实例了初始化,反应到字节码操作指令中是
类的初始化方法是 <clinit>()
实例的初始化方法是 <init>()

任何一个类的初妈化都要求它的所有祖先类(而不是祖先接口)预先被初始化。而一个接口的初始化,并不要求它的祖先接口预先被初始化。

类有主动初始化和被动初始化,如new和使用静态字段,还有我们一定用过 Class.forName() 方法,它还有一个重载方法 forName(String name, boolean initialize, ClassLoader loader),一个参数的forName,默认的initialize 是 true,即加载后就初始化。

只有注册用户登录后才能发表评论。


网站导航: