类装载过程,以及什么时候会装载一个类
类装载过程
具体内容参考博文http://blog.****.net/lincolnmi/article/details/50538016
Java虚拟机通过装载、连接和初始化一个Java类型,使该类型可以被正在运行的Java程序所使用
--也就是说要想使用一个类,必然会经历过上面的三个过程
装载时会做两项检查,虽然在验证阶段之前进行,但逻辑上属于验证阶段。
- 验证class文件格式是否正确,如魔数,每个部分在正确位置,正确的长度,文件的长度不是太长或太短等。 保证正式解析二进制class文件时候,不会造成虚拟机的崩溃。
- 确保每个除Object之外每个类都有一个超类,加载某个类的时候,确保该类的所有超类必须加载。
废话不说,上图
一。装载
注意:我们在java程序中new一个对象的时候,其实是访问了类对应的Class对象,所以在多线程的时候,Synchronized(类名.class),其它线程就不能创建对象了。
二。连接 :连接的过程是将类初始化为jvm运行时可用的类型
连接分为验证,准备,解析
1.验证:确认它是否符合java的语义 ,如
- 检查final的类不拥有子类
- 检查final方法不能被覆盖
- 确保类型和超类型之间没有不兼容的方法申明(比如两个方法签名完全一样,但返回类型不同)
- 检查所有的常量池入口相互之间保持一致(比如CONSTANT_String_info入口的string_index项目必须是一个CONSTANT_Utf8_info入口的索引)
- 检查常量池中所有的特殊字符串(类名,字段名,方法名,字段描述符和方法描述符)是否符合格式
- 检查字节码的完整性
在准备阶段,java虚拟机为类变量分配内存,并设置默认的初始值。在正式初始化之前,类变量都没有被正式初始化为真正的初始值
3.解析
解析过程是在类型的常量池中寻找,类,接口,方法的符合引用,把这些符号引用,变成直接引用。解析这个过程什么时候执行是虚拟机自己决定的,可以在初始化阶段后面执行。
解释一下是什么意思:废话不说,上图
可以参考http://blog.****.net/qq_19740679/article/details/48133871
三。初始化
为类的静态变量赋初始值
四。接下来我们讨论一下具有继承关系的类之间的类初始化(<clinit>)和对象初始化(<init>)之间的关系
上来给结论: 父类的静态块 > 子类的静态块 > 父类的构造快 > 子类的构造块
废话不说,上图
解释一下运行的过程:首先在test中遇见A,此时载入类A,这个时候遇见A继承了B,载入B,同理再载入C,此时再进行初始化,从父类的静态块开始,然后是子类的静态块。
之后我们new了一个A对象,从父类的构造块开始,然后是子类的构造快
所以说构造快包括:类的构造快,类的构造方法。执行顺序:先执行类的构造块,然后执行类的构造方法