时间:2021-05-19
前言
上一篇我们知道了一个类的生命周期是:加载->验证->准备->解析->初始化->使用->卸载。
当初始化完成以后,一个类所有的类变量(被static修饰的变量)都被赋值。但是未被static修饰的成员变量又是何时被赋值的呢?
一个类何时会被初始化
一个类何时被初始化可以分为以下几类:
我们来说道说道第3点和第6点
我们平常在使用main方法和调用某个类的静态方法的时候,是不是发现,并不能直接调用静态方法和main方法所在类的非静态方法和非静态变量。
可是明明不是说了在调用静态方法和执行main方法的时候,所在的类已经被初始化了吗?
是的!在上一章节我们就说,类初始化的时候会按照我们编写代码的顺序为类变量(static修饰的变量)进行赋值。注意哦,此时这个类仅仅只有静态变量被正确赋值了哦。
public class People{ private static String name ="lisi"; private int age = 18; static{ name ="zhangsan"; }}如上述代码,在该类被初始化之后,首先按照代码顺序将类变量(被static修饰的变量)赋值。所以name被赋值"lishi",然后再将name赋值为 "zhangsan"。此时age并没有值,直接直接调用会报错。
一个类何时被实例化
上一个章节中,我们明白了加载->验证->准备->解析->初始化的具体细节。
当初始化完成后,一个类的静态变量被正确赋值。如果这个对象是被new出来的。那么在初始化完成之后会进入实例化阶段。
实例化的具体步骤为:
父类非静态成员初始化语句(包括代码块,按照在类定义中的顺序执行)->父类构造函数->子类非静态成员初始化语句(包括代码块,按照在类定义中的顺序执行)->子类构造方法()
注意哦!
如果这个类有父类不光是先实例化父类。整体流程如下:
1. 加载父类
1.1 为静态属性分配存储空间并赋初始值
1.2 执行静态初始化块和静态初始化语句(从上至下)
2. 加载子类
2.1 为静态属性分配存储空间
2.2 执行静态初始化块和静态初始化语句(从上至下)
3. 加载父类构造器
3.1 为实例属性分配存数空间并赋初始值
3.2 执行实例初始化块和实例初始化语句
3.3 执行构造器内容
4. 加载子类构造器
4.1 为实例属性分配存数空间并赋初始值
4.2 执行实例初始化块和实例初始化语句
4.3 执行构造器内容
实例化的内存模型
到这里,我们就非常的清楚为什么在静态方法中不能直接调用非静态的变量,因为此时的非静态变量并没有被赋值。
以前我在学习的时候,new一个对象出来大家总是在说,我们初始化了这个对象,然后balabala。。。
导致我对于初始化和实例化里的静态变量和非静态变量何时被赋值一直有点模糊。new一个对象出来准确的来说是进行了初始化和实例化两个步骤,这样应该就会清晰了很多。
初始化完成以后,类被存放在方法区,注意哦,此时并没有存放在堆内存中。
只有当对象实例化进入堆内存中以后才会对非静态变量进行初始化赋值。
总结
这下总算吧一个类的初始化和实例化的细节搞明白了,关于文中的方法区,堆内存等内容,下一节再具体分析。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
一、类的初始化对于类的初始化:类的初始化一般只初始化一次,类的初始化主要是初始化静态成员变量。类的编译决定了类的初始化过程。编译器生成的class文件主要对定义
类的初始化 在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值。 在程序中,静态变量的初始化有两种途径: 1.在静态变量的声明处进行
在考虑类初始化时,我们都知道进行子类初始化时,如果父类没有初始化要先初始化子类。然而事情并没有一句话这么简单。首先看看Java中初始化触发的条件:(1)在使用n
Java在构造函数中,第一行会先调用父类中构造函数进行初始化。父类初始化完毕后,再对子类的属性进行显示初始化。进行子类构造函数的特定初始化。初始化完毕后,将地址
Java中初始化块详解在Java中,有两种初始化块:静态初始化块和非静态初始化块.静态初始化块:使用static定义,当类装载到系统时执行一次.若在静态初始化块