新手求问java类的加载顺序,初始化顺序,继承关系中构造器的调用等一系列问题,能否给我详细讲讲程序的执行过程。
最近自学java,看<think in java>到第7章了,很多东西感觉都已经明白,但在自己脑子里感觉全乱的,没有形成体系。我自己写了一个程序如下:
package reusing;
class Xx{
Xx() { System.out.println("Xx constructor"); }
}
class Zz{
Zz() { System.out.println("Zz constructor"); }
}
class Yy {
Xx x=new Xx();
static Zz zz=new Zz();
Yy() { System.out.println("Yy constructor"); }
}
class Aa extends Yy{
Aa(int i) { System.out.println("Aa constructor"); }
Xx xx=new Xx();
static Bb bb=new Bb();
}
class Bb {
Bb() { System.out.println("Bb constructor"); }
}
public class Cc extends Aa {
Bb b = new Bb();
Cc(){
super(1);
System.out.println("Cc constructor");
}
public static void main(String[] args) {
Cc c = new Cc();
}
}
结果为:
Zz constructor
Bb constructor
Xx constructor
Yy constructor
Xx constructor
Aa constructor
Bb constructor
Cc constructor
对于这段程序的完整执行流程我还是很不太明白的地方。我把自己理解的程序的执行过程描述一下,不懂和有错的地方希望大神们给我解惑一下,有点啰嗦,大家见谅。
1.首选程序要访问Cc.main方法,就必须加载Cc这个类(Think in java 上说类是在任何static 成员被访问时加载的)。
2.然后由关键字extends得知Cc类有一个父类Aa所以就加载Aa类
3.继续由Aa类发现父类Yy,然后加载Yy
4.然后看Yy类中有没有static变量需要初始化,没有,再看Aa中有没有,结果有static Bb b,所以进行初始化,这时候加载Bb类,并调用了构造函数,所以输出了第一条结果:Bb constructor
5.然后看Cc类有没有static 成员需要初试话,没有,所以开始执行main方法
(有点不太明白,书上说static变量是在类加载的时候初始化的,既然类加载的顺序是从导出类向上到基类,那为什么最开始初始化的还是父类的static 变量?这不是互相矛盾吗? 我自己的理解是,导出类还没加载完,就去加载它的父类了,意思是加载到Aa类,但还没加载到初始化static Bb bb的时候,就去加载Yy类了,然后把Yy类加载完,再继续回来加载Aa类,所以才先初始化父类的静态变量,不知道我这种解释对不对,请大神们给我讲解下)
6.执行Cc c = new Cc(); 语句创建一个Cc类的对象
从这里开始完全不明白了,为什么是先进行的最上面基类的初始化,再调用构造器,然后依次是导出类。导出类对父类构造器的显示调用感觉一点用都没有啊,super(1)那句话明明在Cc类的构造器中,可是Cc类中bb变量的初始化却又比构造器中的输入语句先执行,有点晕了,语言组织能力有点差,希望大家明白我的困惑,谁能给我解释下原理,还是说我自己理解的整个执行过程都是错的?