Class加载过程&类加载器&双亲委派

Class加载过程&类加载器

1.Class cycle

  1. loading:
    把class文件load进内存中去,它本来是class文件中一个个的二进制字节,装载完成就进入Linking阶段
  2. Linking:
    1. Verification:校验装进来的class文件是否符合class文件的标准,假如你装进去的不是CA FE BA BE,在这步就会被拒绝掉
    2. Preparation:是把class文件静态变量赋值,不是赋初始值,例如类int i类型的数字赋值5时。会先把值赋值为0,再由Initlalizing将5赋值给当前变量
    3. Resolution:是把常量池中用到的符号引用,要把他转化为直接的内存地址,直接可以访问到的内容
  3. Initlalizing:
    将静态变量的的初始值这个时候才赋值,例如上面的 i在此时由0赋值为5

Loading过程

  • load过程中类加载器的双亲委派机制,如下图
    在这里插入图片描述

  • 双亲委派机制

    • 这里的父加载器指的不是当前加载器的父类加载器,也不是当前加载器的加载器。指的是当前类的中的一个父加载器类型的成员变量
    • 双亲委派过程是
      • 在当前类加载器的缓存检查是否存在,如果没存在的话就向器父加载器中进检查是否已经加载过。以此类推知道到顶层的bootstrap都没有的话,就反向从上往下委托其子加载器加载,一层一层加载,如果最后没有加载出来就抛出ClassNotfound。
    • 为什么要双亲委派机制
      • 主要是为了安全,如果没有改机制,那么任何一个自定义加载器都可以讲任何类加载到内存中
      • 假如我们自定义的加载器对String类进行加载,覆盖之前的加载,那么就会十分的危险。存在泄密的风险
      • 是有了双亲加载就会不一样,我们的在加载java.lang.string的类时就会,在当前加载器中查找,没有的话就直接向上检查(不允许直接将其加载)。结果我们就直接在最上层的bootstrap中找到,所以就直接返回并不会在进行二次加载。

打破双亲委派

  • 如何打破:重写loadClass()方法
  • 什么时候打破过
    • JDK1.2之前,自定义ClassLoader都必须重写loadClass()
    • ThreadContextClassLoader可以实现基础类调用实现类代码,通过thread.setContextClassLoader执行
    • 模块化的时候使用热启动和热部署

自定义类加载器

  • 继承ClassLoad
  • 重写模板方法findClass
    • 调用defineClass

ClassLoader源码解析

  • 类加载的过程就是,上来先找,我有没有加载过,这个catch里有没有,如果有就直接返回,没有就去父类加载,父加载器上来也是在catch中找。一直到顶层都没有,再向下层层委托加载,最终是当前加载器进行加载。

Lazyloading

  • 懒加载,jvm并没有规定何时加载,jvm虚拟机的实现都是用的懒加载。懒加载就是我什么时候使用,才去加载这个类
  • 但是虽然没有规定加载,却严格规定了初始化
    • New getstatic putstatic invokestatic指令,访问final变量除外
    • Java.lang.reflect对类进行反射调用时
    • 初始化子类的时候父类首先初始化
    • 虚拟机启动时,被执行的主类必须出啥化
    • 动态语言支持java.lang.invoke.MethodHandle解析结果为REF_getstatic REF_putstatic REF_invokestatic方法句柄时,该类必须初始化
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值