在Java中,所有文件都是一个类,类的初始化无处不在。那么,Java在类初始化时到底做了什么呢?在此记录一个小练习,通过输出,我们可以比较清晰地看出Java在类的初始化时,工作顺序是怎样的。

 1 public class Insect {
 2     
 3     private int i = 9;
 4     protected int j ;
 5     public Insect() {
 6         // TODO Auto-generated constructor stub
 7         print("i =" + i + ", j = " + j );
 8         j = 39;
 9     }
10     
11     private static String x1 = print("static Insect.x1 initialized");
12     
13     private static String print(String str){
14         System.out.println(str);
15         return "47";
16     }
17     
18 }
19 
20 public class Beetle extends Insect{
21     private String k = print("Beetle.k initialize");
22     private static String t = print("static Beetle.k initialize");
23     public Beetle() {
24         print("k =" + k);
25         print("j =" + j);
26     }
27 
28     public static void main(String[] args) {
29         print("Beetle.k initialize start");
30         Beetle beetle = new Beetle();
31     }
32     
33     private static String print(String str){
34         System.out.println(str);
35         return "48";
36     }
37 
38 }

运行上面的程序,会输出以下结果:

static Insect.x1 initialized
static Beetle.k initialize
Beetle.k initialize start
i =9, j = 0
Beetle.k initialize
k =48
j =39

 

下面,我们对输出结果进行一下分析。

首先,上面有两个类,一个Insect,一个Beetle,其中Insect是Beetle的父类。其中入口是Beetle父中的main方法。

 

程序首先会想要执行main方法,但是它在加载Beetle方法时,会发现Beetle是有父类的。所以它会转到父类,先加载父类。

 

所以程序的第一步是执行第11行,private static String x1 = print("static Insect.x1 initialized"); 初始化 static成员;

加载完父类Insect之后,程序会开始加载子类Beetle,因此第二步会执行第22行,private static String t = print("static Beetle.k initialize");初始化 子类的static成员;

完成之后,程序终于进入了main方法,于是执行了第29行,print("Beetle.k initialize start");直接输出;

接着要获取Beetle实例,即会调用Beetle的构造方法。但是Beetle是有父类的,所以程序会先调用父类的构造方法第7、8行 , 输出i和j的值;

在构造了父类之后,程序再构造子类,但是在执行构造方法前,会先完成成员的构造,所以会先执行第21行,private String k = print("Beetle.k initialize");初始化String k;

最后,程序才会执行Beetle的构造方法,执行第24、25行,创建一个Beetle对象,对输出k和j的值。

 

Done

 

posted on 2015-08-30 15:50  Fishbonell  阅读(203)  评论(0编辑  收藏  举报