类的加载机制

作者: 金馆长说 | 来源:发表于2018-07-23 22:00 被阅读8次

类不被初始化的情况

  1. 对于静态字段,只有直接定义这个字段的类才会变初始化,子类引用父类的静态字段不会导致子类的初始化,只会初始化父类。
public class SuperClass {
    static {
        System.out.println("SuperClass init!");
    }
    public static int value = 123;


}

public class SubClass extends SuperClass {
    public static int aa=32;
    static {
        System.out.println("SubClass init!");
    }
}

  1. 数组的定义不会导致类的初始化
 SuperClass[] sca = new SuperClass[10];
  1. 使用静态常量不会导致类的初始化,因为常量在编译阶段就会存入调用类的常量池,本质上没有引用到定义类的常量,类在被编译成class之后,静态常量和类就没有关系了。

public class ConstClass {

    static {
        System.out.println("ConstClass init!");
    }

    public static final String HELLOWORLD = "hello world";

}


 public class Test {

    @org.junit.Test
    public void test() {
        System.out.println(ConstClass.HELLOWORLD);
    }

}  

类加载过程7阶段

加载、验证、准备、初始化和卸载这5个阶段的顺序是确定的,类的加载过程必须按照这个顺序按部就班的执行。

何时会执行加载的第一个过程?
这么五种情况是肯定会执行的

  1. 在遇到new 、读取或者设置一个类的静态字段(final除外,final在编译期间就放入了常量池)的时候,以及调用一个类的静态方法的时候。
  2. 使用反射调用的时候,如何类没有被初始化则会先触发其初始化。
  3. 类没有没有初始化的时候,如果其父类没有初始化。则需要先触发其父类的初始化。
  4. 执行一个main()方法
  5. 当使用JDK 1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。


    类的加载过程7个阶段

1. 加载

  • 加载是类加载的过程的一个阶段,加载到我们的JVM需要需要经过三个过程
  1. 通过一个类名来获取到此类的二进制字节流
  2. 将字节流的静态存储结构转化为方法区运行时的数据结构
  3. 在内存中生成这个类的 Class对象,作为方法区的访问入口。


    JVM加载类图示过程
几种类加载器

2. 验证

  • 验证这个步骤按照深入JAVA虚拟机一书描述的是,很重要的一个步骤。因为这个步骤需要保证,加载进来的Class文件是符合虚拟机规范的,并且不会对虚拟机造成安全危害,这个阶段只要有以下三个操作。
  1. 文件格式验证
    这个步骤主要是检查字节流是否符合Class文件格式规范,是否以魔数0xCAFEBABE开头,版本号,常量问题。

下面是一个class得二进制字节码,cafe开头的就是魔数,它是JAVA之父自己定义的一个规则,CafeBabe代表咖啡宝贝,这个也符号Java的咖啡标志。


魔数
  1. 元数据验证
    这个阶段只要是对字节码进行语义分析,以保证字节码符合Java语义的规范,可能包含的检查有这个class是否有父类,是否集成了不允许继承的类比如final修饰的类,是否实现了父类要求实现的接口,字段是否产生了矛盾。

  2. 字节码验证
    这阶段是验证中最复杂的一步,主要是确定class的语义是否合法、符合逻辑,对类的方法体进行验证分析,保证类的方法不会对虚拟机安全造成危害。

  3. 符号引用验证
    这个阶段主要是检查class的一些访问修饰符是否符合规范,符号引用验证的目的是确保解析动作能正常执行。

3. 准备

准备阶段是正式为类变量分配内存并设置类初始值的阶段,分配static修饰的变量,这些变量所使用的内存都将在方法区中分配。

  public static int value = 123

value变量在被分配的时候,它的值不会是123而是默认的0。因为这个过程还未执行到Java代码,赋值为123的操作将在初始化阶段完成。

4. 解析

  • 解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,
  1. 符号引用以一组符号来描述所引用的目标,它可以是新形势的字面量。
  2. 直接引用是指向目标的指针、相对偏移量或者一个能直接定位到目标的句柄。

解析类型主要有

  1. 类接口的解析
  2. 字段解析
  3. 类方法解析
  4. 接口方法解析

5. 初始化

类初始化是类加载过程中的最后一步,到了初始化阶段虚拟机才真正开始执行Java程序代码,准备阶段变量已经赋值过系统要求的初始值,而初始化阶段则回去初始化class的类变量和其他资源。

6. 使用

到了使用这一步就说明class已经正确的执行完了类加载的过程,class已经被加载到了虚拟机中,能被Java代码正确调用的过程。

7. 卸载

该类所有的实例都已经被GC,也就是JVM中不存在该Class的任何实例。

  • 加载该类的ClassLoader已经被GC。
  • 该类的java.lang.Class 对象没有在任何地方被引用,如不能在任何地方通过反射访问该类的方法

相关文章

  • 类加载机制(一)

    加载机制系列类加载机制(一)类加载机制(二)类加载机制(三) 类加载机制 1.JVM把class文件加载到内存,对...

  • 类加载机制(三)

    加载机制系列类加载机制(一)类加载机制(二)类加载机制(三)类加载器 这里引用尚学堂的的几张图片 demo: 结果:

  • JVM——类加载机制

    前言 今天就来介绍类的加载机制以及双亲委派机制。 JVM 类加载机制 JVM 类加载的五个阶段 JVM 类加载机制...

  • 类加载机制(二)

    加载机制系列类加载机制(一)类加载机制(二)类加载机制(三)类的加载全过程中的主动引用与被动引用 类的主动引用(会...

  • 类加载机制

    类加载机制 类加载机制是指 .class文件加载到JVM,并形成Class对象的机制。 类加载机制可以在运行时动态...

  • 从萌新的角度理解Java类加载机制

    类加载机制 本文主要是对java中类加载机制的入门级别文章,主要介绍类加载机制基本概念,以及类加载机制主要内容。本...

  • 从类加载开始的JVM学习

    目录 引言 java类加载流程 java类加载机制- 类加载原理- 双亲委派机制 Tomcat中双亲委派机制的应用...

  • java基础知识,JVM虚拟机类加载机制

    知识要点: 类加载机制简介 类加载机制流程 类加载机制简介 虚拟机把描述类的数据从Class文件加载到内存,并对数...

  • 3:类加载机制深度解析(Tomcat打破双亲委派机制)(文末有项

    1:Tomcat的类加载机制 2:Tomcat的类加载机制流程图 3:Tomcat的类加载机制总结 4:代码实战 ...

  • 【JAVA】京东一面

    1、类加载机制概念、加载步骤、双亲委托机制、全盘委托机制、类加载器种类及继承关系 2、如何实现让类加载器去加载网络...

网友评论

    本文标题:类的加载机制

    本文链接:https://www.haomeiwen.com/subject/liksmftx.html