一、观察一段源码与结果
public class StaticOrder
{
static{
System.out.println("我是此类中的第一个出现的静态代码块");
}
{
System.out.println("我是此类中的第一个出现的非静态代码块");
}
public static void main(String[] args)
{
createObject();
createObject();
}
public static void createObject(){
System.out.println("创建类对象前");
StaticOrder so = new StaticOrder();
System.out.println("创建类对象后");
}
{
System.out.println("我是此类中的第二个出现的非静态代码块");
}
static{
System.out.println("我是此类中的第二个出现的静态代码块");
}
}
结果:
我是此类中的第一个出现的静态代码块
我是此类中的第二个出现的静态代码块
创建类对象前
我是此类中的第一个出现的非静态代码块
我是此类中的第二个出现的非静态代码块
创建类对象后
创建类对象前
我是此类中的第一个出现的非静态代码块
我是此类中的第二个出现的非静态代码块
创建类对象后
二、结果分析与总结
从上面的小程序可以看出,静态代码块在加载类时执行,当静态代码块的有多个时,执行顺序依照静态代码出现的先后顺序。(当然类只加载一次,所以静态代码块在程序的生命周期中也只执行一次)
非静态代码块在创建对象时执行(不必创建引用变量),且在构造函数前执行。(具体的原因可以参考李刚老师的“疯狂Java程序员的基本修养”一书)
总体上看,三者的执行顺序为:静态代码块 ——>非静态代码块——>构造函数。
三、作用
静态代码块主要就是在加载的时候执行,而且只执行一次,有唯一性,写在构造器中没有太大意义,例如jvm
加载HibernateUtil类时,只执行一次,获取一个sessionFactory实例
非静态代码块,个人感觉没什么用,也可放到构造函数方法体的前面部分,得到同样的效果。
构造函数用于实例化对象时,初始化一些必要信息。如创建一个复杂的窗体界面可以放在构造函数中。