Java中的代码块系列1——静态代码块和构造代码块的调用机制


Java中有代码块分为4种:普通代码块、构造断码块、静态代码快、同步代码块。

普通代码块指的就是一般方法中的花括号的代码段。

构造代码块就是在类中,不属于任何方法的代码段(当然是在花括号内)。

静态代码块就是在类中,不属于任何方法的代码段,并且“{”的前面有static。

同步代码块用在线程间。


今天,将对静态代码块和构造代码块的调用机制做出一些测试。

package JLearner.codeblock;

public class Parent {

	{
		//构造代码快
		System.out.println("Parent'  Block");
	}
	
	static{
		//静态代码快
		System.out.println("Parent'  Static Block");
	}

	public Parent() {
		System.out.println("Parent'  Constructor");
	}
	
	public static void StaticMethod()
	{
		System.out.println("Parent'  StaticMethod");
	}
	
}
package JLearner.codeblock;

public class Child extends Parent {
	{
		//构造代码快
		System.out.println("Child'  Block");
	}
	
	static{
		//静态代码快
		System.out.println("Child'  Static Block");
	}

	public Child() {
		System.out.println("Child'  Constructor");
	}
	
	public static void StaticMethod()
	{
		System.out.println("Child'  StaticMethod");
	}
}


下面的各个部分分别执行,即保证是程序第一次调用。

执行效果即输出在注释里,总结也看注释

package JLearner.codeblock;

public class RunTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		//每当生成子类的对象时,它的加载顺序值得记住它:
		//首先是执行所有静态代码块,先是父类的,然后是子类的
		//接下来是非静态部分(构造)
		//然后执行父类的构造代码块,之后是父类的构造方法(即构造代码块在构造函数之前被执行)
		//然后执行子类的构造代码块,最后是子类的构造方法
//		new Child();
	/*	
		Parent'  Static Block
		Child'  Static Block
		Parent'  Block
		Parent'  Constructor
		Child'  Block
		Child'  Constructor
*/
		
		//当调用子类的静态方法时,父类和子类都是要加载的,所以两个类的静态代码块被首先调用
		//之后直接调用子类本身的静态方法
		//注意:只是调用类的静态方法,而不生成对象的话,构造代码块不会被执行
//		Child.StaticMethod();
/*	
 		Parent'  Static Block
		Child'  Static Block
		Child'  StaticMethod
*/
		
		//调用父类类似
//		Parent.StaticMethod();
/*		
		Parent'  Static Block
		Parent'  StaticMethod
		*/
		
		
		//连续生成两个子类对象,可以发现:
		//静态代码块只会在程序运行第一次加载相应或者相关(如父子关系)的类时才会被调用
		//也就是说静态代码块只会被调用一次
		//而构造代码块则是每次生成对象时都会被调用
//		new Child();
//		new Child();
/*		
		Parent'  Static Block
		Child'  Static Block
		Parent'  Block
		Parent'  Constructor
		Child'  Block
		Child'  Constructor
		Parent'  Block
		Parent'  Constructor
		Child'  Block
		Child'  Constructor
*/		
		
		
		
		//那么怎么算是加载类呢?即什么样的操作被认为是第一次加载类呢?
		//这里做了另外2个实验。
		//之前的new操作(生成对象),毫无疑问,将对对象所对应的类以及其对应的父类(或者父类的父类。。。)进行加载
		//注意:而 “类名.class”是不会加载类的。
		//从下面的例子可以看到:
		//静态代码块没有被执行
		//System.out.println(Child.class.toString());
/*		
		class JLearner.codeblock.Child
		*/
		
		
		//而使用Class.forName是会加载类的,也就是说,使用Class.forName可能执行类的静态代码块
//		try {
//			Class.forName("JLearner.codeblock.Child");
//		} catch (ClassNotFoundException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
/*		
		Parent'  Static Block
		Child'  Static Block
		*/
		
		
		
		
	}

}



你可能感兴趣的:(Java中的代码块系列1——静态代码块和构造代码块的调用机制)