类加载优先级

    笔者将通过本文向大家介绍一下Java中的类加载顺序,既然是一门编程语言,那么纯说理论是不行的,应该通过实践来验证理论,理论来指导实践。下面笔者就来写一个验证类加载优先级的Java demo供大家学习和参考。
/**
 * 
 * @author Liangyj
 *加载优先级:1.静态变量和静态代码块(类加载时执行,只加载一次并且常驻内存)、静态方法(只加载一次并且常驻内存,直接使用类名调用时才执行)
 *-->2.构造代码块(创建对象时执行)-->3.构造方法(创建对象时执行)-->4.普通方法(创建对象并调用时执行)
 */
public class TestJava {
	public static void main(String[] args) {
		System.out.println("我是main方法A:"+A+",B:"+B);
	}
	//构造方法
	public TestJava(){
		B = 10;
		A = 4;
		System.out.println("我是构造方法A:"+A+",B:"+B);
	}
	//构造代码块
		{
			A = 3 ;
			B = 3;
			System.out.println("我是构造代码块!A:"+A);
		}
	//静态变量
	private static int B = 1;
	
	//静态代码块
	static {
		A = 2 ;
		B = 2;
		System.out.println("我是静态代码块:"+"B:"+B);
	}
	
	//静态变量
	private static int A = 1;
}
class RunTest{
	@SuppressWarnings("static-access")
	public static void main(String[] args) {
		TestJava testJava = new TestJava();
		testJava.main(args);
	}
}

下面是控制台输出结果:
我是静态代码块:B:2
我是构造代码块!A:3
我是构造方法A:4,B:10
我是main方法A:4,B:10

偶然间笔者在网上看到有人写了关于类加载顺序的文章,并贴出了Java demo,最后得出了加载顺序的结论。但是笔者发现文章的作者写的代码并不严谨,得出的结论并不完全正确。因为光看在控制台输出的顺序,并不能完全说明Java的类加载顺序。比如,在加载优先级为同级时,加载和输出结果的顺序是根据代码的上下文顺序来决定的,这并不能说明优先级的高低。所以笔者在这里加以说明,以此做个提醒。笔者在代码中特意将优先级高的放在比它优先级低的代码后面,以此更为直观的证明它的优先级更高,而不是因为代码顺序导致。本Java demo纯属笔者原创,根据自己思路所写。为了方便大家代码阅读,笔者将RunTest类和TestJava类放在同一个.java文件中(为新手朋友稍作解释,老手无视即可)。

    年后回来有个小伙伴问了我个问题(如果你是一个细心的、爱思考的读者,相信你也会发现这个问题,但是并没有读者在笔者的博文下留言提问,笔者有点小小的失落,不知大家是浅尝辄止没有注意到,还是自己知道其中的道理,好了,言归正传),正好适合放在这里做引申:
    1.声明与赋值的关系(或顺序)
    2.初始化加载和创建对象时加载,以及方法调用时加载
先对第一点作出解释:在上面的代码中静态变量A,似乎是先被静态代码块赋值了,再声明的变量类型,为何该代码能通过编译呢?其实不然,虽然在上面我们已经得出了类的加载顺序,静态变量和静态代码块的优先级是相同的,此时根据代码顺序加载,但是变量(属性)的声明是先于赋值的,这是由类加载机制决定的,类的加载机制可参考: http://blog.csdn.net/boyupeng/article/details/47951037
再解释第二点:静态变量、静态代码块、静态方法是在类被加载时就初始化加载,但静态方法作为一个函数(方法)不会直接执行,同样需要被调用才执行,只不过不需要创建一个新的对象,因为它是先于对象存在的,而构造代码块和构造函数(方法)是在创建对象时加载,普通方法在被调用时才加载。
    另外注意:静态语句块中只能访问到定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态语句块可以赋值,但是不能访问。结合笔者给的demo,在上述代码中,静态代码块中给A赋值(A = 2)是可以编译通过的,而如果要引用变量A(例如输出语句改为打印A的值)则会报错:不能在定义字段之前引用字段(报错信息的中文翻译)。  --2017/2/3引申补充
    原文永久地址: http://jsonliangyoujun.iteye.com/blog/2348180

猜你喜欢

转载自jsonliangyoujun.iteye.com/blog/2348180