Wiky's Blog

java基础知识篇之调用顺序

看到Java编程思想里面提到的父子类构造器的调用顺序,再加上自己对static的理解,特地写了这个博文。
例子1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class AA{
AA(int id){
System.out.println("A"+id);
}
}
class BB {
BB(int id){
//System.out.println(id);
System.out.println("B"+id);
}
}
class CC extends BB{
private BB a=new BB(1);//
CC(int id){
super(id);//从B100再到B1可以看出调用顺序为先父类构造器,再到自己的域的声明
System.out.println("C"+id);
}
}
public class DD extends CC{
public static int sid=1;
static{sid++;}
public int id=100;
public static BB b1=new BB(sid);
private AA a=new AA(id);//A
private BB b=new BB(id);//B
static{sid++;}
private CC c=new CC(id);//BC
{//代码块和域执行顺序为同等级别,按顺序执行
sid++;
id++;
}
DD(){
super(sid);
System.out.println("D"+id);
}
public static void main(String[] args){
new DD();//
}
}

输出:
B2
B3
B1
C3
A100
B100
B100
B1
C100
D101
总结:
1.首先static的域和代码块按照顺序执行,这一部分只会执行一次;
2.调用基类的构造器,这个步骤会一直反复递归的执行下去;
3.按照声明的顺序调用成员的成员方法,声明和代码块均是;
4.调用导出类的构造器主体。

例子2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class A{
A(){
System.out.println("befor print");
print();
System.out.println("after print");
}
void print(){
System.out.println("A .print");
}
}
class B extends A{
private double radio=1.0;
B(double radio){
this.radio=radio;
System.out.println(radio);
}
void print(){
System.out.println("B.print");
System.out.println(radio);//可以看到输出结果为0而不是1
}
}
public class ConductorTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
new B(5.0);
}
}

输出:
befor print
B.print
0.0
after print
5.0

//这个0.0说明了,在所有步骤之前,分配给对象的存储空间都为二进制的0;
//然后再调用基类的构造器;然后再到声明顺序调用成员的初始化方法;
总结起来就是:
1.首先static的域和代码块按照顺序执行,这一部分只会执行一次;
2.分配给对象的存储空间都为二进制的0;
3.调用基类的构造器,这个步骤会一直反复递归的执行下去;
4.按照声明的顺序调用成员的成员方法,声明和代码块均是;
5.调用导出类的构造器主体。

热评文章