Java对象初始化和多态
2019-04-19 本文已影响0人
Mick米壳
加载 Load
- 根据一个类的全限定名来读取此类的二进制bytestream(并不一定要从class文件中获取,可以通过其他渠道,譬如jar、zip、数据库、动态编译的java源文件、本地系统直接加载、通过网络)
- 将bytestream代表的静态存储结构转换为方法区的run-time structure(类型信息)
- 在堆中生成一个对应的java.lang.Class对象(类对象),作为方法区类型信息的访问入口
- Loading和Linking的部分内容交叉进行,但开始时间存在顺序
链接 Linking
验证 verification
- 验证bytecode,file format(class文件格式),metadata,symbol reference(确保resolution能正常进行),即是否符合虚拟机的要求且不会危害虚拟机的安全
- 重要但非必要
准备 Preparation
- 为类中的静态分配内存,并设定默认值(static final 例外,会直接赋值)
解析 resolution
- 将方法区中对象类型信息的符号引用->直接引用(即类、接口、字段、接口方法、方法类型、方法句柄、调用点限定符这7类符号引用在内存中的指针偏移量),这一阶段可以在初始化之后,运行之前进行
- 完成方法表的填充
初始化 Initializaiton
- <clint>:包含static非final变量初始化语句,static代码块。根据语句出现顺序执行
- static语句快只能访问定义在其之前的变量
- JVM保证一个类的<clint>执行之前,它的超类<clint>方法已经被执行
- <clinit>方法被JVM加锁
- 如果一个类没有声明任何的类变量,也没有静态代码块,那么可以没有类<clinit>方法
- 触发初始化的时机:new,反射,序列化,static方法、字段,main(),父类
- 初始化不同于实例化(<init>),后者的触发条件为new、clone等,顺序为父类->子类,变量->语句块->构造函数,<init>之前必须由<clinit>初始化过