Java类加载过程和双亲委派机制总结

Java类加载过程

加载

  • 通过类名去查找获取此类的二进制流
查找war、jar、网络中获取...
  • 将该类所代表的静态存储结构转化为方法区运行时数据
可反推方法区(持久代)保存了类信息
  • 在内存中生成一个代表该类的对象,作为方法区这个类的放问入口。

验证

因为class二进制流可以来源的地方很多,所以需要确保该class文件的字节流中包含的信息复合虚拟机要求,不会伤害虚拟机自身。主要分为4个阶段:

  • 文件格式验证:编码、头部
  • 元数据验证 :java语义校验
- 这个类是否有父类,是否继承了不能继承的类(final)
- 这个类是否实现了父类的所有抽象方法
  • 字节码验证
如检查int中是否存了long的数据、指令会不会跳出方法体以外
  • 符号引用验证
主要是在接下来解析时验证,判断引用的对象是否能找到对应的类、是否能运行被访问

准备

为类变量赋初值(注:类变量是被static修饰的变量)

解析

对类、接口、字段、方法进行解析

初始化

程序员通过程序制定主观计划区初始化类变量和其他资源

类加载器

Hotspot从jvm角度讲,只有两种类加载器:

  1. 启动类加载器:底层c++实现,是虚拟机的一部分
  2. 其他的类加载齐:java实现,独立于虚拟机外部,全部继承于java.lang.ClassLoader.

双亲委派模型

工程过程
  1. 一个类加载器收到了类的加载请求,首先检查请求的类是否已经被加载过,如果没有
  2. 自己先不做加载,而是把这个请求委派给父类加载器
  3. 父类加载器继续向上抛,只有当父类加载器反馈自己无法完成这个加载请求,子类才会尝试自己加载

原理

// 首先检查请求的类是否已经被加载过
Clas c = findLoadedClass(name);
if(c == null){
    try{
        if(parent != null ){
            c = parent.loadClass(name,false);
        }else{
        //如果没有父类加载器,则尝试用启动类加载器加载
            c = findBootstrapClassOrNull(name);
        }
    }catch(ClassNotFoundException e){
        如果父类抛出改方法,证明父类加载器不能完成加载请求
    }
    if(c == null){
        // 调用本身的findcalss方法加载。
        c = findClass(name);
    }
}

优点

实现了java类加载的一种带有优先级层次的关系,保证了java程序的稳定运作。

你可能感兴趣的:(java学习)