java中静态块与非静态块以及自由块与构造函数执行顺序分析
package cn.kml.forserver20130730;/** * 定义一个用于测试自由块以及构造器执行顺序的父类 * @author 柯美玲 QQ:794950040 */public class Detail{public static int a;public Detail(){//构造器System.out.println("Detail构造器");}{//非静态块System.out.println("Detail非静态"); }static{//静态块System.out.println("Detail静态块");}public static void main(String[] args) {System.out.println("main1");Detail detail=new Detail();}}
?
***********************运行结果*********************
?
?
在此刻,你是不是觉得很神奇!为什么构造函数不是最先执行的?你是不是开始怀疑我的结果,
其实不用怀疑,谁试谁知道………………
?
?
在了解具体的原因之前,让我们先来看一下,当一个程序执行时,需要做哪些准备工作。
那当然就是类装载器要把程序装载到虚拟机上。装载过程分为三个部分:装载,链接和初始化。
其中链接又分为三部分:校验,解析,准备。下面分别列出具体作用:
? ? ? ? ? ? ? ? ? ? ? 装载:查找和导入类或接口的二进制数据
? ? ? ? ? ? ? ? ? ? ? 链接:进行下面三个步骤,其中解析步骤是可选择的。
? ? ? ? ? ? ? ? ? ? ? 校验:检查导入类或者接口的二进制数据是否正确
? ? ? ? ? ? ? ? ? ? ? 解析:将符号引用转成直接引用
? ? ? ? ? ? ? ? ? ? ? 准备:给类的静态变量分配并初始化储存空间
? ? ? ? ? ? ? ? ? ? ? 初始化:初始化静态变量以及执行静态块代码
如下图所示:
? ? ? ? ? ??
?
?
所以说,由上面可以得出,静态变量的分配空间与初始化以及静态自由块的执行都是在.class
文件加载时,也就是主函数执行之前。
?
总结:
? ? ? ? ? ?**************************静态块与非静态块***************************
? ? ? ? ? ?java中一个类中除了有属性,方法之外,还可以有自由块。
? ? ? ? ? ?自由块又可以分为静态块和非静态块。
? ? ? ? ? ?虽同为自由块,但静态块和非静态块的执行是有很大区别的。
? ? ? ? ? ?由本文最初给出的程序及结果可知:
? ? ? ? ? ?静态块最先执行,而且只会执行一次;
? ? ? ? ? ?而非静态块是在每次实例化类的对象时执行的,而且执行在构造器之前。
?
? ? ? ? ?***********************静态属性与一般属性**************************
? ? ? ? ?静态属性的初始化是在类装载过程中切只执行一次,先于主函数的执行 ? ?
?
? ? ? ? ?非静态属性的初始化在实例化对象时,先于构造器的执行 ?
? ? ? ?
? ? ? ? ? 当类与类之间存在继承关系时:如下
? ? ? ? ? ? ?
package cn.kml.forserver20130730;/** * 定义一个用于测试自由块以及构造器执行顺序的子类,继承Detail类 * @author 柯美玲 QQ:794950040 */public class subDetail extends Detail{public subDetail(){//构造器System.out.println("subDetail构造器");}{ //非静态块 System.out.println("subDetail非静态块"); } static { //静态块System.out.println("subDetail静态块"); } public static void main(String args[]){ System.out.println("subDetailmain"); subDetail te=new subDetail(); } }
?运行结果:
? ? ? ? ? ? 当存在继承关系时,先执行父类的静态块,再执行子类的静态块
? ? ? ? ? ? 接下来执行子类的主函数
? ? ? ? ? ?若实例化子类的对象,先执行父类的非静态块,再执行父类的构造函数
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 然后执行子类的非静态块,最后执行子类的构造函数
?
? ? ? ? ? ?再如以下程序:
? ? ? ? ? ? ? ? ? ? ? ? ? ??
package cn.kml.forserver20130730;/*** 定义一个用于测试自由块以及构造器执行顺序的子类,继承subDetail类 * @author 柯美玲 QQ:794950040 */public class subbDetail extends subDetail{public subbDetail(){//构造器System.out.println("subbDetail构造器");}static{//静态块System.out.println("subbDetail静态快");}{//非静态块System.out.println("subbDetail非静态快");}public static void main(String[] args) {System.out.println("subbDetail main");subbDetail sDetail = new subbDetail();}}
? ? ? ? ? ? 运行结果:
? ? ??
?
由以上结果显而易见,自由块与构造器的执行顺序。
?
?
?
?纪念整整崩了15次的google浏览器!!
?
?
?
?
?