您的位置:首页 > 编程语言 > Java开发

Java类加载机制

2020-02-02 01:51 555 查看

一. 类加载机制三大步骤

1. 加载

  • 获得二进制流:获得.class文件的字节流,有多种方式获得.class文件,如:zip包、网络、运行时计算生成等。
  • 数据类型转换:将上一步的字节流以一定的数据结构(魔数、主次版本号、访问权限、常量池、字段表、方法表、属性表等)保存至方法区。
  • 生成Class对象:在内存中生成一个代表该类的java.lang.Class对象。一般情况下,该类是在堆中的,但对于HotSpot虚拟机,则保存在方法区中。

2. 连接

  • 校验 四大阶段 Class文件格式校验(魔数、主次版本号...)
  • 元数据校验(是否有父类...)
  • 字节码校验(把一个子类对象赋值给父类数据类型,这是安全的...)
  • 符号引用校验(通过全限定名是否能找到对应的类...)
  • 作用? 确保.class文件的字节流数据符合当前虚拟机的要求,并保证虚拟机的安全。
  • 准备
      作用? 为类变量在方法区分配内存,并设置零值。
  • 解析
      作用? 虚拟机将方法区中常量池的符号引用替换为直接引用。

    3. 初始化

    • 作用? 将用户指定的值赋给类变量,以及执行静态代码块。
    • 类变量赋值与静态代码块赋值顺序? 顺序执行,后面的覆盖前面的!
    public class ClassLoaderSequence {
    
    public static int id = 1;
    
    static {
    age = 10;
    id  = 2;
    }
    
    public static int age = 20;
    }
    
    @Test
    public void staticExcSequenceTest(){
    System.out.println("id  = " + ClassLoaderSequence.id);  // 2
    System.out.println("age = " + ClassLoaderSequence.age); // 20
    }

     

    二. 类加载器分类

    • 引导类加载器(Bootstrap ClassLoader)
    • 扩展类加载器(Extension ClassLoader)
    • 系统类加载器(System ClassLoader)
    • 用户类加载器(User ClassLoader)

     

    三. 疑问

    1. 什么时候触发类加载的加载阶段?

    • 运行时,用到某个类时。遇到四大字节码指令。
      new关键字实例化对象。
    • 读取(getStatic)、设置(putStatic)类字段。
    • 调用类方法(invokeStatic)。
  • 对类进行反射调用。
      调用java.lang.reflect包中方法。
  • 父类尚未加载。
      当初始化某个类时,若发现该父类尚未初始化,则优先触发父类初始化。

     

    • Java虚拟机规范允许系统预加载某些类。哪些类? 系统经常用到的,如:java.util.*、java.lang.*、sun.reflect.*
    • 如何证明? 启动项目时添加-XX:+TraceClassLoading虚拟机参数。

     

    四. 参考

      本文中,有很多细节没有展开论述,原因是因为有篇很好的文章(https://www.geek-share.com/detail/2654448200.html)已经讲得很清楚了,我也就没有必要再做赘述。

    • 《深入理解Java虚拟机》第七章    - 虚拟机类加载机制
    • 《疯狂Java讲义》          第十八章 - 类加载机制与反射(上半部分)

     

    转载于:https://www.cnblogs.com/YaoFrankie/p/11442934.html

    • 点赞
    • 收藏
    • 分享
    • 文章举报
    b55000458515493 发布了0 篇原创文章 · 获赞 0 · 访问量 23 私信 关注
  • 内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: