1、类加载的生命周期
验证、准备、解析放在一起称为连接。
2、加载calss文件到内存
(1)加载
a、文件位置,文件格式是jar还是class(获取二进制字节流)
b、静态存储结构转化为方法区的运行时数据结构
c、在java堆里面生成一个类对象,作为方法区的访问入口
运行时数据区:
方法区和栈为运行时数据区所有线程共享,new的对象都在堆里面,
(2)验证
a、验证class文件的标识:魔数
b、验证文件的版本号
c、验证常量池(常量类型(14种)、常量类型数据结构是否正确、方法能不能被正确调用、utf-8是否符合标准)
e、class文件的每个部分(字段表、方法表)
f、元数据验证(父类验证、继承验证、final验证)
g、字节码验证(指令验证)
h、符号引用验证(通过符号引用是否能够找到字段、方法、类)
(3)准备
a、为类变量(静态变量)分配内存并且设置类变量的初始化阶段(只对static类变量进行内存分配)
static int n=2;
初始化的值是0,而不是2,。因为这个时候还没有执行任何java方法(clint)
static final int i=2;
对应到常量池在准备阶段就被赋值为2。
(4)解析
对符号引用进行解析:把符号引用指向直接引用(指向目标的指针或者偏移量),主要涉及类、接口、方法等
a、字段的解析
在本类中去找有没有匹配的字段,如果类中有接口,往上层接口找匹配的字段,搜索父类,如果找不到,出现错误:NoSuchFieldError,找到了,但是没有权限:IIIegalAccessError
public class mytest extends Thread implements Serializable,Comparable { int num=9;//字段
本类>>接口>>父类
b、类方法的解析
在本类中查找有没有匹配的方法,没有的话去父类查找,还没有的话去接口列表里面去查找
接口里面找到了,但是本类没有,说明本类是一个抽象类,查找结束,抛出AbstractMethodError,如果没有找到:NoSuchMethodError
c、接口方法的解析
在本类中查找有没有匹配的方法,找到的话直接返回,否则,到父类的接口中递归查找,如果没有找到:NoSuchMethodError
(5)初始化
clint:静态变量和静态块的初始化
static int num=0; static { System.out.println("ni hao!!"); }
init:类的初始化,类的实例化构造器
jvm:虚拟机类加载机制(类加载生命周期、加载calss文件到内存)
原文:https://www.cnblogs.com/zhai1997/p/12573697.html