一、触发初始化的条件
1.实例化创建对象
2.访问静态变量或为静态变量赋值
3.调用静态方法
4.使用java.lang.reflect包下的方法对类进行反射调用方法
5.子类进行初始化,如果父类没有被初始化,那么父类会进行初始化
6.指定一个含有main方法的启动主类时,会先初始化主类
二、Java类的生命周期
装载---------->连接(验证---------->准备---------->解析)---------->初始化----------使用---------->卸载
(图稍微丑了些0.0)
当我们编写完源代码之后,这时储存的文件是Java后缀的格式。
通过Javac命令将Java源代码文件编译为字节码文件-----------class文件。
---------------------------------------------------------------------------------------------------------------------------------
装载
通过获取全限定类名,获取该类的二进制字节流,也就是class文件的二进制数据读取到内存当中。
将字节流代表的静态存储结构转化为方法区的运行时动态数据结构。
classLoader将类加载,然后将类的类型信息保存在方法区,并在堆中生成一个 java.lang.class对象。这个class对象为程序访问类型信息提供了方法入口。
连接
验证
1.class文件格式验证
2.元数据验证:符不符合java语法规范
3.字节码验证
4.符号引用验证
准备
为类变量,也就是static静态变量在方法中分配内存空间,并赋上默认值。
static final修饰的常量会在准备阶段就赋上指定的值。
解析
将常量池中的符号引用转化为直接引用。
符号引用指向的目标不一定已经加载到内存当中。
初始化
会将类变量进行真正赋值。按照代码顺序运行被static修饰的静态代码块和静态变量。
如果静态变量定义在静态代码块后,允许静态代码块为静态变量赋值,但不允许访问。
实例化
创建对象的方法
1.new
2.通过反射获取class对象,然后用newInstance()
3.通过clone
4.通过Constructior类 constructor.newInstance()
5.反序列化
当我们创建对象时,这时候类才会进行实例化,执行非static代码的赋值或执行,为实例变量在堆中分配内存,初始化值。