Class文件的执行:
1、Loading(加载)→2、Linking(连接)→3、Initializing (验证)
一、Loading:
ClassLoader:负责载入系统的所有Resources(Class,文件,来自网络的字节流 等),通过ClassLoader从而将资源载入JVM中去运行。
JDK中很多的类加载器,但他们作用范围不同各司其职执行时也分层级(不是继承关系)!但所有的类加载器都源于ClassLoad这个抽象类。
当一个类被Loading到JVM内存后会生成java内置的Class对象,通过Class对象获取整个字节码文件信息并实例化对象。
ClassLoader 的等级加载机制(不是继承关系):
BootstrapClassLoade ------ 是Java中最顶层的类加载器,加载JVM运行时所需要的核心类及jar包
ExtClassLoader ------拓展类及jar加载 目录:C:\Program Files\Java\jre1.8.0_201\lib\ext\xxx.jar
AppClassLoader--------加载用户自定义的类(ClassPath路径)(xxxx.class→ClassLoader→CodeSegment内存中(动态加载机制)
BootstrapClassLoad(c或c++制作的)加载其他ClassLoader,再由其他ClassLoader加载指定类文件
双亲委派机制:分层加载(自上而下)保证核心类库的安全,classLoad(类加载器)都会有个getParent()方法指向自己的对象由哪个classLoad加载到内存中的-父加载器(这样防止运行时上层classLoader二次加载)
自定义类加载器:继承ClassLoad抽象类,重写findClass方法(得到文件IO)中调用defineClass方法(将二进制转成Class对象)并返回Class对象
LazyLoading的五种情况:
-
new、getstatic、putstatic、invokestatic 指令,访问final变量除外!
-
java.lang.reflect对类进行反射调用时
-
初始化子类时,先初始化父类
-
虚拟机启动时,被执行的主类会被初始化
-
动态语言支持java.lang.invoke.MethodHandle解析结果为REF_getstatic REF_putstatic、 REF_invokestatic的方法句柄是,该类必须初始化
二、Linking
1.Verification
验证文件是否符合JVM规定
2.Preparation
静态成员变量赋默认值
final成员变量(基础类型)已经赋值完成
static final int value=123(属于特殊情况:Preparation期间就赋值完成)
3.Resolution
将类、方法、属性等符号引用解析为直接引用 常量池中的各种符号引用解析为指针、偏移量等内存地址的直接引用
三、Initializing(初始化)
给静态成员变量赋初始值
调用类构造器方法(也就是静态代码块) <clinit>
四、实例化
2.成员变量赋默认值
3.调用构造方法(对象构造器方法)<init>
1.调用父类的构造方法
2.成员变量顺序赋初始值
3.执行构造方法中代码