大家好,又见面了。 本文简单的记录几个与类加载相关的知识点。
几个概念说明
static静态代码块
- 一般用于初始化类中的静态变量。比如:给静态的数组或者list变量赋初值。使用static静态代码块进行初始化与直接在定义变量的时候初始化效果是一样的。
- static静态代码块其实完全可以看做是一个没有名字、没有参数、没有返回值的静态方法,这个静态方法会在main方法执行前执行,而且是主动执行的,不需要任何显示调用,除此之外它和普通的静态方法没有任何区别。
构造块(又称构造代码块)
- 没有static修饰的代码块;
- 主要用于普通变量的初始化。
类的初始化顺序
在一个独立的类中
优先按照如下的顺序执行初始化:
- 所有static修饰的全局变量(
static、static final
等)、静态代码块,按照代码顺序从上到下逐个执行一遍。- 所有普通全局变量、普通代码块(又称为构造块、构造代码块),按照代码顺序从上到下逐个执行一遍。
- 构造函数。
如果new多个类对象,则只有第一个new对象的时候,会执行上述1中描述的代码初始化,后面new对象的时候,都只会执行2、3两个步骤。即:static修饰的静态变量、静态常量、静态代码块,在整个虚拟机生命周期中只会初始化一次。
在子类中初始化顺序
对于子类的初始化,整体原则是优先执行父类的初始化,然后再执行子类的初始化,详细如下:
- 按照从最顶层父类逐层下钻,直到当前要初始化的子类的顺序,先将所有static修饰的全局变量(
static、static final
等)、静态代码块,按照代码顺序从上到下逐个执行一遍(即先执行父类中所有static相关代码,再执行子类中static相关代码)。- 按照从最顶层父类逐层下钻,直到当前要初始化的子类的顺序,依次执行上述1个独立类初始化章节中提及的2、3步骤。
举个例子,class Child extends Parent
,加载顺序如下:
- 加载Parent中所有的static相关代码;
- 加载Child中所有的static相关代码;
- 加载Parent中的普通变量或者普通代码块(又称为构造块、构造代码块);
- 加载Parent的构造函数;
- 加载Child中的普通变量或者普通代码块(又称为构造块、构造代码块);
- 加载Child中的构造函数。 如果执行多次new对象操作,则从第二次new对象的时候,只会执行3、4、5、6四个步骤。
如果new多个类对象,则只有第一个new对象的时候,会执行上述1中描述的代码初始化,后面new对象的时候,都只会执行2步骤。即:static修饰的静态变量、静态常量、静态代码块,在整个虚拟机生命周期中只会初始化一次。
我是悟道,聊技术、又不仅仅聊技术~
如果觉得有用,请点赞 + 关注让我感受到您的支持。也可以关注下我的公众号【架构悟道】,获取更及时的更新。
期待与你一起探讨,一起成长为更好的自己。