随笔-55  评论-208  文章-0  trackbacks-0
昨天在改一处代码时发现执行的过程和预想的不一样,仔细探究才发现是构造器执行顺序问题.(汗自己一下,基础不够扎实)
特地做了一些尝试然后把java构造器的执行顺序整理出来.
首先是我测试的代码:
public class Son extends Father {
    SonProp r 
= new SonProp();
    
public Son() {
        System.out.println(
"Son is construct");
    }

    
public static void main(String[] args) {
        
new Son();
    }

}

class Father {
    FatherProp SonProp 
= new FatherProp();
    
public Father() {
        System.out.println(
"Father is construct");
    }

}

class SonProp {
    
public SonProp() {
        System.out.println(
"SonProp is construct");
    }

}

class FatherProp {
    
public FatherProp() {
        System.out.println(
"FatherProp is construct");
    }

}
执行结果如下:
FatherProp is construct
Father is construct
SonProp is construct
Son is construct

由此不难看出java类初始化时构造函数调用顺序:
  (1)初始化对象的存储空间为零或null值;
  (2)按顺序分别调用父类成员变量和实例成员变量的初始化表达式;
  (3)调用父类构造函数;(如果实用super()方法指定具体的某个父类构造函数则使用指定的那个父类构造函数)
  (4)按顺序分别调用类成员变量和实例成员变量的初始化表达式;
  (5)调用类本身构造函数。

posted on 2008-05-27 11:43 rocket 阅读(8106) 评论(6)  编辑  收藏 所属分类: 经验积累

评论:
# re: 一个以前没有注意的问题:java构造函数的执行顺序 2008-05-27 11:46 | 基金净值
我也才知道,谢谢!  回复  更多评论
  
# re: 一个以前没有注意的问题:java构造函数的执行顺序 2008-05-27 12:30 | 隔叶黄莺
借用我在 http://www.blogjava.net/cheneyfree/archive/2008/05/24/202643.html 里写的回复,再次贴来这里来,与博主共勉

1. 初始化分为为的初始化和实例的初始化
2. 每个类在 JVM 中都对应一个 Class 实例
3. 父类实例是作为子例的部分存在的 (Class 实例之间也存在父子关系)
4. 初始化实例之前要初始化类

基于以上几点就可以理解以下初始化顺序
1. 父类静态属性、静态类 (父类的初始化,对应 JVM 方法 cinit())
2. 子类的静态属性、静态类 (子类的初始化,对应 JVM 方法 cinit())
3. 父类的实例构造,实例变量初始化 (实例变量初始实际会放到 JVM 的 init() 中)
4. 子类的实例构造,实例变量初始化 (也是对应的 init() 方法)

关于类的 Class 实例,可以回想 Log 的声明
Log log = LogFactory.getLog(TestClass.class);
也就是无论你,new 多少个 TestClass 实例,它们对应着同一个 TestClass 的 Class 实例,也就是为什么很多地方把静态方法、静态属性说成是类的方法、类的属性,其实质就是在 JVM 中存在同一个 Class 实例的方法、属性,也就能保持一致性。

关于父类实例是作为子类的一部分存在,可借鉴 C++ 或是有面向对象特性的 C 函数库(如 gtk),来理解,父类实例会居于子类实例的首地址,所以对子类转型成父类实例时,它是安全的,因为首地址一样的,所以从首地址到 size(父类)就是父类实例地址空间,到size(子类)就是子类实例的地址空间。  回复  更多评论
  
# re: 一个以前没有注意的问题:java构造函数的执行顺序 2008-05-27 13:02 | rocket
@隔叶黄莺

呵呵,还是我们的黄莺扎实啊,以前还真没有仔细研究过jvm。这就去仔细找资料看看。  回复  更多评论
  
# re: 一个以前没有注意的问题:java构造函数的执行顺序 2008-05-27 17:33 | deathnote
笔试了几次,基础很重要啊,收下了。。。。  回复  更多评论
  
# re: 一个以前没有注意的问题:java构造函数的执行顺序 2008-05-28 20:49 | Jack.Wang
LZ 真强大,看来你的 oo 还是不行啊!
最近听一个牛人(国外留学的 doctor),讲中间件的时候讲几次内存模型。真的受益匪浅,改天去你们公司分享一下!  回复  更多评论
  
# re: 一个以前没有注意的问题:java构造函数的执行顺序 2012-08-08 10:54 | 王鹏飞
不错,很有帮助  回复  更多评论
  

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


网站导航: