我们先来看实验代码:
public class StaticGzJt {
//构造方法
public StaticGzJt(){
System.out.println("构造方法...");
}
//构造代码块
{
System.out.println("构造代码块...");
}
//静态代码块
static{
System.out.println("静态代码块+【static】...");
}
//静态方法
public static void doSomting(){
System.out.println("静态方法...");
}
}
//静态、构造、静态代码块运行顺序
new StaticGzJt().doSomting();
执行结果:
静态代码块+【static】...
构造代码块...
构造方法...
静态方法...
为什么执行顺序是这样的?我们来看一下编译后的代码:
package others;
//编译后的代码
public class StaticGzJt {
public StaticGzJt() {
System.out.println("构造代码块...");
System.out.println("构造方法...");
}
public static void doSomting() {
System.out.println("静态方法...");
}
static {
System.out.println("静态代码块+【static】...");
}
}
这下是不是清楚了,构造代码块 {} 中的执行内容被提到了构造方法的最前面中去执行,而 static {} ,依然在静态方法中,根据执行顺序 ,静态方法在 构造之前加载,而类静态又在静态方法之前,那么疑问又来了,为何静态方法在最后执行呢? 这个是因为我们调用的缘故:
//调用方法
new StaticGzJt().doSomting();
我们如此调用当然最后才会执行
public static void doSomting() {
System.out.println("静态方法...");
}
嗯 ,没错的,静态方法会在构造之前进行加载,且只加载一次。
那么问题来了,如果我们直接调用静态不实例化呢?
//直接调用静态方法
StaticGzJt.doSomting();
运行结果:
静态代码块+【static】...
静态方法...
这样来看,只有实例化后才会加载构造方法,从而我们得出结论:
静态在类加载时执行( 且先加载类静态,再加载静态方法 ),构造在类实例化时执行。