首先解释下,初始化代码块的定义,代码举例
public class Test {
{
//初始化代码块
}
Test(){
System.out.println("constructor ");
}
int i = 0;
public void print(){
System.out.println("print");
}
}
在类的里面,所有的方法的外面定义的代码块称之为初始化代码块如上。能够用static修饰初始化代码块,使之成为静态初始化代码块,如下例
public class Test {
static{
//静态初始化代码块
System.out.println("static block");
}
Test(){
System.out.println("constructor ");
}
int i = 0;
public void print(){
System.out.println("print");
}
}
初始化代码块的执行时机,举例说明
package staticBlock;
public class Test {
int i = 1;
static{
System.out.println("static initialize block");
}
{
System.out.println("i = "+ i);
System.out.println("initialize block");
}
Test(){
System.out.println("constructor ");
}
public static void print2(){
System.out.println("static method");
}
public void print(){
System.out.println("normal method");
}
public static void main(String [] args){
// Test.print2();
Test t = new Test();
Test t2 = new Test();
t2.print();
}
}
运行结果:
static initialize block
i = 1
initialize block
constructor
i = 1
initialize block
constructor
normal method
将注释的部分解开(绿色代码)运行结果如下:
static initialize block
static method
i = 1
initialize block
constructor
i = 1
initialize block
constructor
normal method
总结:
1.结果都是首先打印出static initialize block 说明静态初始化代码块的执行先于初始化代码块。
2.详细说明静态初始化代码块的执行时机。
首先无论是执行Test.print2();或者 Test t = new Test(); jvm都要从硬盘找到Test .class文件,读入这个文件,然后解释执行。读入这个文件的过程是这样的,jvm会自动通过CLASSPATH环境变量,去硬盘上寻找相应的Test .class文件,找到这个文件后,会把这个文件中所保存的Test类的信息读入到jvm中,并保存起来。上述的这个过程(黄绿色)称之为类加载,当jvm第一次遇到某个类时,就会执行这个类加载的过程,而静态初始化代码块会在类加载的时候执行,所以两个执行结果都是首先打印static initialize block
3.初始化代码块的执行时机。
打印了两次
i = 1
initialize block
constructor
而我们创建了两个对象,这说明初始化代码块是在我们创建对象时执行的,也就是说我们每次创建对象都要执行这个初始化代码块,而且是在对象的成员变量赋值之后,对象的构造器之前执行的。