类加载机制

概念

当程序需要用到某一个类时,如果这个类没有加载到内存中,那么JVM会通过加载、链接、初始化这三个步骤来实现类的初始化。
在这里插入图片描述

过程

加载

加载是指通过类的全限定名找到类的class文件,然后将该文件的二进制字节流读入内存,生成java.lang.Class实例对象。
类被加载到内存中,会生成两部分,一部分是class文件的内容,一部分是class类的对象,这个对象指向这些内容。
在这里插入图片描述

链接

链接包括三部分,验证、准备、解析。

验证

验证阶段主要是验证被加载进来的类的内部结构是否符合规范,主要包括文件格式验证,元数据验证、字节码验证、符号引用验证。

文件格式验证:主要是验证字节流是否符合Class文件格式规范,是否能被当前JVM处理。
元数据验证:主要是对字节码进行语义分析,分析其是否符合Java语言规范。
字节码验证:主要是对方法体进行验证,如果一个方法体的字节码无法通过字节码验证,则代表这个方法体有问题,但是通过的话也没办法保证一定没有问题。
符号引用验证:主要将符号引用转为直接引用,这个验证发生在 解析阶段 ,通过类的全限定名查找对应的类,如果没有找到则没办法通过符号引用验证,符号引用验证是为了保证解析阶段的正常执行。

准备

给类的静态变量分配内存空间,并赋予初始默认值。(例如 private static int i=10; 这里的默认初始值并不是10,而应该是0。)
实例变量并不会分配空间,在对象实例化时,才分配空间。由于是静态变量,所以内存都在方法区中分配。值得注意的是,被static final int i=3,在准备阶段会被赋值为3。

解析

将常量池中的符号引用转为直接引用,符号引用是以一组符号来描述所引用的目标,直接引用是指可以直接指向目标的指针、相对偏移量等。

初始化

给类的静态变量赋予真正的初始值,即上诉所说的10。



类加载器

启动类加载器

启动类加载器是最顶级的加载器,它由原生代码实现,而不是继承与ClassLoader,它用来加载Java的核心类。

扩展类加载器

扩展类加载器,用来加载JAVA的扩展库,JVM提供一个扩展库,扩展类加载器就是在这里面查找类并加载的。

系统类加载器

它的父类是扩展类加载器,加载的是当前classpath下的所有类。

双亲委派机制

原因

由于在Java中,对类的唯一标识是全限定名,而JVM对类的唯一标识是类的全限定名和加载它的类加载器,所以引出了双亲委派机制。

概念

1、当有类需要被加载时,系统类加载器先去缓存判断是否已经加载过此类了,如果没有就委托给上级扩展类加载器。
2、扩展类加载器去缓存判断是否已经加载过此类了,如果没有就委托给上级启动类加载器。
3、启动类加载器去缓存判断是否已经加载过此类,如果没有就去加载目录查看自己是否能够加载此类,如果不能就让下一级扩展类加载器。
4、扩展类加载器在自己的加载目录查看自己是否能够加载此类,不能就交给下级。
5、系统类加载器到自己的加载目录查看是否可以加载此类,如果可以就加载并存入缓存,如果不行则返回失败。

作用

1、向上委托,能够防止我们重写了核心类,例如 String.class
2、防止全限定名一样的类被重复加载了。(见上面原因)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值