前言
那一年,呼延十又回想起被加载顺序支配的恐惧,笔试题上,好几个类,几个方法,几个输出语句,让你按照顺序写出输出.我真的是有一句…
但是呢,我们还是有了解一下的必要的,在编码过程中有许多的应用.
正文
经常用来比较顺序的,无非就是静态代码块,普通代码块,静态方法和普通方法.
这里直接说一下结论:
先静态后普通最后构造方法,先父类后子类.
看一下实际的例子:
package daily;
/**
* created by huyanshi on 2019/1/28
*/
public class ClassLoadOrder {
public static void main(String[] args) {
B b = new B();
}
}
class A {
private int i = aFunc();
static {
System.out.println("A-----static");
}
public int aFunc() {
System.out.println("A----- default");
return 1;
}
public A() {
System.out.println("A----- constructor");
}
}
class B extends A {
private static int i1 = staticFunc();
public B() {
System.out.println("B----- constructor");
}
static {
System.out.println("B----- static");
}
private int i = bFunc();
private static int staticFunc(){
System.out.println("B----- static func");
return 111;
}
public int bFunc() {
System.out.println("B----- default");
return 2;
}
}
他的输出是什么呢?
A-----static
B----- static func
B----- static
A----- default
A----- constructor
B----- default
B----- constructor
我们来跟随顺序一步一步来一下:
- 首先在main方法中,调用了B类的构造方法.
- 由于B类有父类,因此先加载A类.
- 加载A类的静态代码块,输出
A-----static
. - 加载B类的静态变量,调用了方法,输出
B----- static func
. - 加载B类的静态代码块,输出
B----- static
. - 加载A类的普通变量,
private int i = aFunc();
由于调用了方法,因此输出A----- default
. - 加载A类的构造方法,输出
A----- constructor
. - 加载B类的普通变量,调用了方法,输出
B----- default
. - 加载B类的构造方法,输出了
B----- constructor
.
这些其实是一些记忆内容啦.
在这期间,发现一些小的知识点,也记录一下.
- 静态变量,静态代码块的加载顺序只和代码编写的顺序有关.
- 普通变量及构造方法,顺序一定是先普通变量,再构造方法的.
说好的应用呢
其实我目前对这个知识点应用最多的就是静态代码块.
经常在编码过程中需要给常量的List,Map赋值
,这个时候我们希望程序启动赋值一次即可,而程序中的其他方法可能就需要使用这些常量了,因此一般使用定义常量Map,并在静态代码块中给其赋值.这样可以保证后续的使用不会拿到空的Map,也保证了只加载这些默认值一次.
完.
ChangeLog
2019-01-28以上皆为个人所思所得,如有错误欢迎评论区指正。
欢迎转载,烦请署名并保留原文链接。
联系邮箱:huyanshi2580@gmail.com
更多学习笔记见个人博客------>呼延十