首先解释下,初始化代码块的定义,代码举例
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 = 1initialize blockconstructori = 1initialize blockconstructornormal method将注释的部分解开(绿色代码)运行结果如下:
static initialize block
static methodi = 1initialize blockconstructori = 1initialize blockconstructornormal 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 blockconstructor而我们创建了两个对象,这说明初始化代码块是在我们创建对象时执行的,也就是说我们每次创建对象都要执行这个初始化代码块,而且是在对象的成员变量赋值之后,对象的构造器之前执行的。