java 类加载顺序 静态变量初始化顺序,何时触发类加载

先用文字描述:

类加载的过程 我自己抽象了下,可以分为

1、装载:查找和导入Class文件 2、3、初始化:对静态变量,静态代码块执行初始化工作


step1. 查找和导入Class文件(包括:二进制代码,class自描述信息)

step2. 链接:其中解析步骤是可以选择的 (a)检查:检查载入的class文件数据的正确性 (b)准备:给类的静态变量分配存储空间 (c)解析:将符号引用转成直接引用

step3. 对静态变量,静态代码块执行初始化工作(注意这里叫初始化--准备静态变量

(step4: init 调用构造方法,一般需要被显示调用 如new ,子类new,反射类方法名等 这叫做实例化


何时类加载被 trigger

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SingletonA a = SingletonA.a;
		
		System.out.println(SingletonB.x);
		System.out.println(SingletonA.x);
		System.out.println(SingletonA.a);
		System.out.println(SingletonB.a);
	}

}

public class SingletonA {  
    private SingletonA(){}  
   
  
    static int x = 0;
    static{
    	x = 5;
    }
    static final SingletonB b = SingletonB.b;  
    static final SingletonA a = new SingletonA();  
    
   
} 

public class SingletonB {  
    private SingletonB(){}  
  
    static final SingletonA a = SingletonA.a; 
    static int x = SingletonA.x; 
    static final SingletonB b = new SingletonB();  
}  
public class Classloader {

	public Classloader() {
		// TODO Auto-generated constructor stub
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SingletonA a = SingletonA.a;
		
		System.out.println(SingletonB.x);
		System.out.println(SingletonA.x);
		System.out.println(SingletonA.a);
		System.out.println(SingletonB.a);
	}

}


在调用 SingletonA a = SingletonA.a; 的时候 就完成了类加载step 1 、2、3


这里 主要讲step3.

prepare : 当一个类 加载自己的时候 完成step1 和 step2,就会进行prepare

如果 A extend B 那么会先prepare B的数据

prepare是 设置所有静态变量的值(全局变量),无论 static 块 还是 static 变量,都是按代码在文中的上下顺序初始化(refer to  http://blog.csdn.net/teaey/article/details/22317989)

遇到 static Object o = new Object();  也会去先初始化 该类,只要是static 都会被初始化出来,简直势如破竹

另外当一个类A 被加载(prepare)到一半的时候,遇到了其他类B的加载,其他类B的加载中又有static A a = new A();

那么这里会直接调用 A的构造方法,哪怕A 中间还有需要static变量未被prepare 完成。

eg 代码例子



public class Classloader {

	public Classloader() {
		// TODO Auto-generated constructor stub
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int n = Child.a;
		// SingletonA a = SingletonA.a;
		// System.out.println(SingletonB.x);
		// System.out.println(SingletonA.x);
		// System.out.println(SingletonA.a);
		// System.out.println(SingletonB.a);
	}

}

class Child extends Father {
	static {
		System.out.println("child static");
	}
	static int a = 1;
	static Father f = new Father();

	static {
		System.out
				.println("child's no block static due to be called init above line:static Father f = new Father();");
	}

	public Child() {
		System.out.println("child init");
	}
}

class Father {
	static {
		System.out.println("father static");
	}
	static Child c = new Child();

	public Father() {
		System.out.println("father init");
	}
}

result output:

father static
father init
child init
child static
father init
child's no block static due to be called init above line:static Father f = new Father();




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值