【java基础】类的初始化与变量内存空间及默认值
-
背景
最近工作中代码使用了static变量,而且对初始化顺序敏感,发现对初始化的理解还有疑惑,因此对初始化这部分进行一次梳理。 -
参考文档
[https://blog.csdn.net/w1196726224/article/details/56529615](Java 类初始化(详解))
https://blog.csdn.net/aaqian1/article/details/113771134 -
开整
类的生命周期一共包括如下几个阶段:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)、卸载(Unloading)。
核心逻辑是以下内容:
- 先初始化类,再初始化类中的实例对象。
a. 初始化类 先初始化类的成员变量(static)及静态代码块,完成后才能调用类方法(static),构造函数属于类方法。
b.初始化对象 先初始化对象的成员变量及代码块,完成后才会调用构造函数,完成对象的初始化。 - 先初始化父类(对象),再初始化子类(对象)。
- 类属性及成员属性会赋默认值,代码块(包括函数)中的变量无默认值,都需要显性初始化。
- 类变量(static)与类代码都保存在方法区中,对象变量保存在对象(堆内存)中,final修饰的变量保存在常量池中。
因此对象的成员变量的完整初始化过程是:
- (有父类时)加载父类代码:
a.静态变量赋默认值(如:int赋值为0)
b.静态变量初始化(如:static int i = 5)
c.执行静态代码块 - 加载类代码:
初始化静态成员变量,过程与父类相同。 - (有父类时)初始化父类实例对象:
a.成员变量赋默认值(如:int赋值为0)
b.成员变量初始化(如:int i = 5)
c.执行代码块
d.执行父类的构造函数 - 初始化实例对象:
过程与初始化父类对象相同。
另外关于常量池:1.7前,常量池内存在代码区(永久代)中,1.7将常量池内存放在堆上,1.7后将常量池内存放在元空间(Meta Space)中。
以上内容,对类变量的初始化过程及内存空间进行了梳理。考虑到变量内存在多线程时的多副本情况,此部分内容下次补充。
第一次写博客,以经常想起的两句诗结尾:
雄关漫道真如铁,而今迈步从头越!

浙公网安备 33010602011771号