Java类加载器(ClassLoader)和类加载过程

类加载器(ClassLoader)是什么?

  • ClassLoader就是用来动态加载class文件到内存中用的(class文件是二进制字节流)
  • 只有加载到内存中的class文件才能被其他class文件引用到

类加载器类型

  • Bootstrap ClassLoader(引导加载器)
  • Extension ClassLoader(扩展加载器)
  • App ClassLoader (应用加载器)

双亲委托模型

  • 每一层上方的加载器称为父加载器,他们之间的父子关系不是通过继承实现的,而是使用组合关系来复用父加载器的代码
  • 加载一个类时,优先请求父类加载器来加载,由上到下依次尝试
    在这里插入图片描述

类加载过程

  • 我们编写的Java程序是由多个class文件组成的,一个类中可能依赖了多个其他的类,当缺少一些class文件的情况下则会出现异常(ClassNotFoundException),程序在加载class文件的时候不会一次性全部加载所有的class文件,而是根据需要通过Java的类加载机制动态的加载所需class文件到内存中。
  • 解析和初始化,不是固定顺序,为了使支持Java方法分派的动态绑定
    在这里插入图片描述

第一步,加载

  • 通过一个类的全限定名来获取其定义的二进制字节流
  • 将这个字节流所代表的静态存储结构转化为方法取的运行时数据结构
  • 在Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口

第二步,验证

  • 为了确保Class文件中的字节流包含的信息符合当前虚拟机的要求
  • 文件格式的验证、元数据的验证、字节码验证、符号引用验证

第三步,准备(Java的语法和类加载紧密相关)

  • 对于基本数据类型(全局的基本类型变量没有赋值的时候可以自动赋默认值,方法中的局部变量需要在编码时手动赋默认值)
  • 被final修饰的变量不会自动赋默认值
    • 对于同时被static和final修饰的变量,必须在声明的时候显示的赋值
    • 对于只被final修饰的变量,可以在声明时显示赋值,也可以在类初始化时为其赋值(例如在构造方法中)
  • 对于引用数据类型reference(系统可以自动赋默认值null)
  • 数组初始化时(系统可以自动赋默认值)

第四步,解析

在这里插入图片描述

  • 类或接口的解析
    • 数组类型还是普通对象
  • 字段解析
  • 类方法解析(先搜索父类,再搜索接口)
  • 接口方法解析(先搜索父接口)

第五步,初始化

  • 初始化阶段是执行类的构造方法的过程

猜你喜欢

转载自blog.csdn.net/yu540135101/article/details/113869622