天天看点

java中静态代码块,类非静态代码块执行顺序

(一) 什么是类的静态代码块 类的非静态代码块

一个类可以使用不包含在任何方法体中的静态代码块,

当类被载入时,静态代码块被执行,且只被执行一次,静态块常用来执行类属性的初始化。

public class testParent {
	static {
		System.out.println("static testParent");
	}
    }
      

 一个类可以使用不包含在任何方法体中的代码块,当类被访问,执行构造函数前置,类会执行不包含在任何方法体中的代码块。

public class testParent {
	public testParent()
	{
		System.out.println("testParent constructor");
	}
	
	{
		System.out.println("blank testParent");
	}
}
      

(二) 代码块的初始化顺序

public class testParent {
	public testParent()
	{
		System.out.println("testParent constructor");
	}
	static {
		System.out.println("static testParent");
	}
	{
		System.out.println("blank testParent");
	}
}
      
public class testChild extends testParent {
	public testChild()
	{
		System.out.println("testChild constructor");
	}
	static {
		System.out.println("static testChild");
	}
	{
		System.out.println("blank testChild");
	}
}
      
public class test {
	public static void main(String[] args) {
		  System.out.println("main Thread start threadid:"+Thread.currentThread().getId());
		  Thread threadTimer = new Thread(new Runnable() {
				@Override
				public void run() {
					System.out.println("child Thread start threadid:"+Thread.currentThread().getId());
					new testChild();
					System.out.println("child Thread end");
				}
			});
		 threadTimer.start();
		 System.out.println("main Thread end");
	  }
}
      

当执行完语句(*)时,打印结果是这样一个顺序 :

main Thread start threadid:1

main Thread end

child Thread start threadid:12

static testParent

static testChild

blank testParent

testParent constructor

blank testChild

testChild constructor

child Thread end

如果我们合并test与testchild。

public class testChild extends testParent {
	public testChild()
	{
		System.out.println("testChild constructor");
	}
	static {
		System.out.println("static testChild");
	}
	{
		System.out.println("blank testChild");
	}
	
	public static void main(String[] args) {
		  System.out.println("main Thread start threadid:"+Thread.currentThread().getId());
		  Thread threadTimer = new Thread(new Runnable() {
				@Override
				public void run() {
					System.out.println("child Thread start threadid:"+Thread.currentThread().getId());
					new testChild();
					System.out.println("child Thread end");
				}
			});
		 threadTimer.start();
		 System.out.println("main Thread end");
	  }
}
      

  执行结果:

static testParent
static testChild
main Thread start threadid:1
main Thread end
child Thread start threadid:12
blank testParent
testParent constructor
blank testChild
testChild constructor
child Thread end
      

分析:在线程中当执行new Child()时,它首先去看父类里面有没有静态代码块,如果有,它先去执行父类里面静态代码块里面的内容,当父类的静态代码块里面的内容执行完毕之后,接着去执行子类(自己这个类)里面的静态代码块,当子类的静态代码块执行完毕之后,它接着又去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法,这个就是一个对象的初始化顺序。

总结:

类的优先级顺序:  

执行类本身中main方法时 :父类静态代码块>>子类静态代码块>>main>>父类非静态代码块>>父类构造函数>>子类非静态代码块>>子类构造函数
      
执行其他类main方法,引用带有静态代码块的类时 :main>>主线程>>父类静态代码块>>子类静态代码块>>父类非静态代码块>>父类构造函数>>子类非静态代码块>>子类构造函数