Java 类加载机制?(深入理解java假造机,P263)
1 什么是类加载?
Java假造机把形貌类的数据从Class文件加载到内存,并对数据进行校验、转换剖析和初始化,最 终形成可以被假造机直接使用的Java类型,这个过程被称作假造机的类加载机制。
一个类型从被加载到假造机内存中开始,到卸载出内存为止,它的整个生命周期将会经历加载 (Loading)、验证(Verification)、准备(Preparation)、剖析(Resolution)、初始化 (Initialization)、使用(Using)和卸载(Unloading)七个阶段,其中验证、准备、剖析三个部分统称 为连接(Linking)。这七个阶段的发生顺序如下图所示。
加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的,类型的加载过程必须按 照这种顺序按部就班地开始,而剖析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始, 这是为了支持Java语言的运行时绑定特性(也称为动态绑定或晚期绑定)。
1 类加载的前置?
javac编译后得到class文件
2 类加载的目的?
把一份被javac编译过的class文件,通过加载生成某种形式的class数据布局进入内存,程序可以调用这个数据布局构造出object:运行时进行。
2 什么时间类初始化?
关于在什么情况下必要开始类加载过程的第一个阶段“加载”,《Java假造机规范》中并没有进行 逼迫约束,这点可以交给假造机的具体实现来自由把握。但是对于初始化阶段,《Java假造机规范》 则是严格规定了有且只有六种情况必须立即对类进行“初始化”(而加载、验证、准备自然必要在此之 前开始):
1.遇到new、getstatic、putstatic或invokestatic这四条字节码指令时,如果类型没有进行过初始 化,则必要先触发其初始化阶段。
能够生成这四条指令的典型Java代码场景有:
- 读取或设置一个类型的静态字段(被final修饰、已在编译期把效果放入常量池的静态字段除外) 的时间。
2 使用java.lang.reflect包的方法对类型进行反射调用的时间,如果类型没有进行过初始化,则需 要先触发其初始化。
3 当初始化类的时间,如果发现其父类还没有进行过初始化,则必要先触发其父类的初始化。
4 当假造机启动时,用户必要指定一个要实行的主类(包含main()方法的那个类),假造机会先 初始化这个主类。
5当使用JDK 7新参加的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例末了的解 析效果为REF_getStatic、REF_putStatic、REF_invokeStatic、REF_newInvokeSpecial四种类型的方法句 柄,并且这个方法句柄对应的类没有进行过初始化,则必要先触发其初始化。
6 当一个接口中界说了JDK 8新参加的默认方法(被default关键字修饰的接口方法)时,如果有 这个接口的实现类发生了初始化,那该接口要在其之前被初始化。
这六种场景中的行为称为对一个类型进行主动引用。
3 类加载的过程?
加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的,类型的加载过程必须按 照这种顺序按部就班地开始,而剖析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始, 这是为了支持Java语言的运行时绑定特性(也称为动态绑定或晚期绑定)。
1 加载
加载:读取class文件,将其转换为某种静态数据布局存在方法区内;并在堆中生成一个便于用户调用的java.lang.Class类型的对象。
2 连接:验证
1 文件格式验证
这个验证实际上发生在第一步加载之前,只有这个验证通过,才会允许字节流进入假造机的方法区中
2 元数据验证、字节码验证:
对类的元数据/字节码进行验证,确保不会危害假造机。
3 符号引用验证:
剖析时发生。
3 连接:准备
为静态变量static赋初始值
常量池、静态变量存储在堆中;
类的元信息存储在方法区,存储方式改成了元空间。
4 连接-剖析:
将常量池内的“符号引用”替换为“直接引用”
1 类或接口剖析
2 字段剖析
3 方法剖析
4 接口方法剖析
剖析完成:说明外部加载的类已经乐成引入程序中。
5 初始化:
判断代码中是否存在主动地资源初始化操作,如成员变量的赋值、静态变量的赋值及静态代码块的逻辑。只有显式的调用new才会调用构造函数进行对象的实例化。
3 创建对象时构造器的调用顺序?
先初始化静态成员,然后调用父类构造器,再初始化非静态成员,末了调用自身构造器。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |