结论:静态块>构造块>构造方法
我们先反着结论定义
public class t {
static int a=1;
t()
{
System.out.print("构造方法");
System.out.println(a);
}
{
System.out.print("构造块");
System.out.println(a);
}
static{
System.out.print("静态块");
System.out.println(a);
a=2;
System.out.println("新值"+a);
}
public static void main(String[] args) {
new t();
}
}
反编译
Compiled from "t.java"
public class r.t {
static int a;
static {
};
Code:
0: iconst_1
1: putstatic #10 // Field a:I
4: getstatic #12 // Field java/lang/System.out:Ljava/io/PrintStream;
7: ldc #18 // String 静态块
9: invokevirtual #20 // Method java/io/PrintStream.print:(Ljava/lang/String;)V
12: getstatic #12 // Field java/lang/System.out:Ljava/io/PrintStream;
15: getstatic #10 // Field a:I
18: invokevirtual #26 // Method java/io/PrintStream.println:(I)V
21: iconst_2
22: putstatic #10 // Field a:I
25: getstatic #12 // Field java/lang/System.out:Ljava/io/PrintStream;
28: new #30 // class java/lang/StringBuilder
31: dup
32: ldc #32 // String 新值
34: invokespecial #34 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
37: getstatic #10 // Field a:I
40: invokevirtual #37 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
43: invokevirtual #41 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
46: invokevirtual #45 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
49: return
r.t();
Code:
0: aload_0
1: invokespecial #49 // Method java/lang/Object."<init>":()V
4: getstatic #12 // Field java/lang/System.out:Ljava/io/PrintStream;
7: ldc #51 // String 构造块
9: invokevirtual #20 // Method java/io/PrintStream.print:(Ljava/lang/String;)V
12: getstatic #12 // Field java/lang/System.out:Ljava/io/PrintStream;
15: getstatic #10 // Field a:I
18: invokevirtual #26 // Method java/io/PrintStream.println:(I)V
21: getstatic #12 // Field java/lang/System.out:Ljava/io/PrintStream;
24: ldc #53 // String 构造方法
26: invokevirtual #20 // Method java/io/PrintStream.print:(Ljava/lang/String;)V
29: getstatic #12 // Field java/lang/System.out:Ljava/io/PrintStream;
32: getstatic #10 // Field a:I
35: invokevirtual #26 // Method java/io/PrintStream.println:(I)V
38: return
public static void main(java.lang.String[]);
Code:
0: new #1 // class r/t
3: invokespecial #59 // Method "<init>":()V
6: return
}
通过汇编代码,我们可以更清楚的发现程序的执行顺序
下面来个"简明"的例子
public class StaticInitBlock {
public static void main(String[] args){
System. out. println("main()");
Tools.t1.f(4);
}
static Tools ts = new Tools();
}
class Tools{
static Tool t1=new Tool(1);
static{
//静态初始化块开始
System.out.println("进入静态初始化块");
t1 = new Tool(11);
t3 = new Tool(33);
t2 = new Tool(22);
System. out. println("退出静态初始化块");
//静态初始化块结束
}
static Tool t2 =new Tool(2);
Tools(){
System. out. println("Tools()");}
static Tool t3 =new Tool(3);
}
class Tool{
Tool(int i){
System. out. println("Tool( "+i+")");
}
void f(int i){
System.out. println("f("+i +")");
}
}
先为静态变量ts分配空间,新建一个Tools对象,加载Tools.class再为static等初始化再···
仔细观察一下就能理解
我们再进行反编译
Compiled from "StaticInitBlock.java"
public class r.StaticInitBlock {
static r.Tools ts;
static {
};
Code:
0: new #10 // class r/Tools
3: dup
4: invokespecial #12 // Method r/Tools."<init>":()V
7: putstatic #15 // Field ts:Lr/Tools;
10: return
public r.StaticInitBlock();
Code:
0: aload_0
1: invokespecial #19 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #30 // String main()
5: invokevirtual #32 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: getstatic #38 // Field r/Tools.t1:Lr/Tool;
11: iconst_4
12: invokevirtual #42 // Method r/Tool.f:(I)V
15: return
}