在java中常见的代码快有静态代码块,构造代码块,局部代码块。



1. 几种代码快的特点:



1.1 静态代码块

    静态代码快:作用在类体中。随着类的加载而加载。常把一些需要在类加载后需要的一些数据放在静态代码块中。



1.2 构造代码快

    构造代码快:作用在类体中。他会在构造方法执行前去执行,并且每执行一次构造方法,构造代码块就会被执行一次。

    什么时候用呢?比如说,我们可以将所有构造方法都要执行的内容,向上抽取将其放入到构造代码块中,使每个重载的构造方法都减少代码量,看起来简洁。



1.3 局部代码快

    局部代码快:因为是局部的,很明显是作用在方法内了。格式:{语句;}。主要用来限定执行的范围。



2. 举例说明执行的顺序

    下面我们通过代码来具体看下这几种代码块的执行顺序:

package com.ilaoda.codeblock;

/**
 * 父类
 * @author 
 */
class Father{
	
	// 父类静态代码快
	static{
		System.out.println("111---父类静态代码快");
	}
	
	// 父类构造代码块
	{
		System.out.println("222---父类构造代码块");
	}
	
	// 父类构造方法
	public Father() {
		System.out.println("333---父类构造方法");
	}
	
	public void hello() {
		// 局部代码块
		{
			System.out.println("444---局部代码块");
		}
	}
}

/**
 * 子类
 * @author iLaoda
 */
class Child extends Father {
	
	// 子类构造方法
	public Child() {
		//super(); 子类构造默认调用父类的无参构造,必须位于子类构造方法内第一行
		System.out.println("555---子类构造方法");
	}
	
	// 子类静态代码块
	static{
		System.out.println("666---子类静态代码块");
	}
	
	// 子类构造代码快
	{
		System.out.println("777---子类构造代码快");
	}
	
	public static void main(String[] args) {
		Child child = new Child();
		Father father = new Father();
		father.hello();	
	}
}
package com.ilaoda.codeblock;

/**
 * 父类
 * @author 
 */
class Father{
	
	// 父类静态代码快
	static{
		System.out.println("111---父类静态代码快");
	}
	
	// 父类构造代码块
	{
		System.out.println("222---父类构造代码块");
	}
	
	// 父类构造方法
	public Father() {
		System.out.println("333---父类构造方法");
	}
	
	public void hello() {
		// 局部代码块
		{
			System.out.println("444---局部代码块");
		}
	}
}

/**
 * 子类
 * @author iLaoda
 */
class Child extends Father {
	
	// 子类构造方法
	public Child() {
		//super(); 子类构造默认调用父类的无参构造,必须位于子类构造方法内第一行
		System.out.println("555---子类构造方法");
	}
	
	// 子类静态代码块
	static{
		System.out.println("666---子类静态代码块");
	}
	
	// 子类构造代码快
	{
		System.out.println("777---子类构造代码快");
	}
	
	public static void main(String[] args) {
		Child child = new Child();
		Father father = new Father();
		father.hello();	
	}
}

    执行结果:

111---父类静态代码快
666---子类静态代码块
222---父类构造代码块
333---父类构造方法
777---子类构造代码快
555---子类构造方法
222---父类构造代码块
333---父类构造方法
444---局部代码块
111---父类静态代码快
666---子类静态代码块
222---父类构造代码块
333---父类构造方法
777---子类构造代码快
555---子类构造方法
222---父类构造代码块
333---父类构造方法
444---局部代码块



3. 分析说明

    因为子类继承父类,所以肯定是类加载器先加载父类。这时,父类静态代码块随着父类的加载而加载,当父类加载完毕后,这时类加载器开始加载子类,子类的静态代码快又随之被加载。由由于子类的创建依赖于父类,所以,在子类的main()方法中首先new一个子类时,此时逻辑调往父类中,父类的构造代码块在父类构造方法前被执行,再执行父类的构造方法。当这些执行完毕后,回到子类中,执行子类的构造方法块,子类的构造方法。

    接下来的一条语句再new Father( )时,同样执行父类的构造代码块,父类构造方法。记住,这时静态代码块不再执行。因为,静态代码块随着类的加载已经加载进来执行过了,并且就只执行这一次。最后,父类的引用调用父类中的一个方法,这个方法中有个静态代码快也随之执行。