类加载

1.1.什么是类加载?

就是.java代码通过javac编译生成.class文件(文件是保存在磁盘上的),如果想要JVM使用这个类,那就需要将这个类加载到内存中,这个过程成为“类加载”。

三个步骤:

  • **1. 加载(loading):**读取.class文件,按照格式来进行解析(.class文件是有固定的格式,javac生成的时候就会按照这个格式来进行组织,JVM加载的时候也会按照这个格式来进行解析)
  • **2. 连接(linking):**一个类可能会依赖其他类,如果想要使用这个类,需要将这个类依赖的类也需要加载
  • **3. 初始化:**创建类对象,初始化该类的静态成员,并且执行静态代码块中的内容

注意:
类型的加载,连接,初始化都是在程序运行期间完成的,(类型:指的是定义的类,接口或者枚举成为类型而不涉及对象,在类加载的过程中,就是一个创建对象之前的一些信息)

示例:

class A{public A(){System.out.println("A的构造");}{System.out.println("A的构造块");}static {System.out.println("A的static块");}
}
class B extends  A{public B(){System.out.println("B的构造");}{System.out.println("B的构造块");}static {System.out.println("B的static块");}
}
public class Test extends B{public static void main(String[] args) {System.out.println("开始");new B();new B();System.out.println("结束");}
}

此时你先可以不用看下面,看看你自己得到的答案是什么,看你是否对这个已经掌握?
输出结果为

对此知道的人就是知道了,不知道的你可能还在疑惑当中,别急,听我细细道来

示例修改:

如果此时Test不继承B,那么输出结果又是如何呢?上面回答错误的老铁给个机会,这次在思考看看有没有进步嘞
输出结果:

结果分析:

1.2.Java中有哪些类加载器?

就是JVM里已经实现好了的类,通过这些特殊的类来具体执行类加载的过程

默认主要有三个类加载器(用户也可以自定新的类加载器):

  • BootstrapClassLoader:专门加载java标准库中的类
  • ExternsionClassLoader:加载一些特殊的类
  • ApplicationClassLoader:加载用户自己写的类
  1. BootstrapClassLoader加载器
    那么标准库的类都在哪里呢?
    如果类在jdk1.8 / jre / lib / rt.jar(可以用压缩包打开),这个文件下,那么就可以使用BootstrapClassLoader加载器来进行加载

  2. ExternsionClassLoader加载器

因为他是加载特殊的类,所以这里就找一个特殊的类来示例
如果类在jdk1.8 / jre / lib / ext目录下,那么就需要通过ExternsionClassLoader加载器来加载

  1. ApplicationClassLoader加载器
    如果类在CLASS_PATH环境变量,或者java -cp指定的目录,或者在当前的目录中,就使用ApplicationClassLoader加载器进行加载

1.3.什么是“双亲委派模型”/“双亲委派原则”?

上面所提到的类加载器之间,其实具有父子关系(但是不是通过类的继承)

  • BootstrapClassLoader 是 ExternsionClassLoader 的父亲
  • ExternsionClassLoader 是 ApplicationClassLoader 的父亲

其实在进行类加载的时候,有一个约定好的顺序

以加载String为例

  1. JVM需要加载类的时候,无论是这个类是什么样的,统一都从Application开始执行
  2. 把类名(java.lang.String)告诉给Application ,Application自身不会真的取进行加载,而是先去找他的父亲Externsion
  3. 当Externsion 拿到这个类名之后同样也不会真的取执行,而是在把任务交给他的父亲Bootstrap
  4. Bootstrap 拿到这个类名的时候,此时它上面没有父亲了,那就只能亲自己加载
  5. 由于String类就在rt.jar 里,此时Bootstrap就加载成功
    6.此时的Externsion 和Application就不需要在进行其他工作了
    总结:遇到类名,先找爸爸,爸爸搞不定,再自己进行加载,如果到最后都找不到就会抛出一个ClassNotFoundExceptin的异常

1.4.自己创建的类加载器是否也要遵循双亲委派模型?是否可以违背?

可以违背,不一定非要遵守,只是标准库中的三个类加载器遵循双亲委派模型
(比如tomcat中的类加载器就没有遵守,webapps 目录中要放很多的.class文件,tomato在执行的时候,实现了自己的类加载器,专门负责从指定的webapps目录中加载对应的类,那么此处就不存在“传递给父类加载器”)

常见面试题

1.什么时候会触发某个类的加载?
答:当使用到一个类的时候,并且该类不在内存中,这个时候就需要加载。那么使用到一个类的时候具体是什么时候呢?

  1. 构造类的实例(new实例的时候)
  2. 使用该类的静态属性/方法
  3. 使用子类的时候,也会触发父类的加载。
    可以综合上面的例题进行分析

看到了写的不错的文章,可供参考

什么是类加载,又有哪些类加载器你真的了解吗?相关推荐

  1. ccs加载out文件_类加载流程、类加载机制及自定义类加载器详解

    原文:juejin.im/post/5cffa528e51d4556da53d091 一.引言 当程序使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载.链接.初始化三个步骤对该类进行类加载 ...

  2. 请你详细说说类加载流程,类加载机制及自定义类加载器

    一.引言 当程序使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载.链接.初始化三个步骤对该类进行类加载. 二.类的加载.链接.初始化 1.加载 类加载指的是将类的class文件读入内存,并 ...

  3. 1.类加载:什么是类加载???什么是类加载器???类加载器有哪三种类型???如何获取类加载器???

    1.类加载:什么是类加载???什么是类加载器???类加载器有哪三种类型???如何获取类加载器??? 学习:第7遍 1.什么是类加载??? 将class文件读取到内存中的过程,称为类加载 2.什么是类加 ...

  4. Tomcat类加载机制与JVM类加载机制对比

    类加载 在JVM中并不是一次性把所有的文件都加载到,而是一步一步的,按照需要来加载. 比如JVM启动时,会通过不同的类加载器加载不同的类.当用户在自己的代码中,需要某些额外的类时,再通过加载机制加载到 ...

  5. 自定义View-实现简易车速器(真的够简易)

    自定义View-实现简易车速器(真的够简易) 学习自定义View挺久了,好久没用都快忘了,这里实现一个简易的车速器算是一个回顾,项目比较简单,代码较少,但自定义View的流程基本都涉及到了.本文不是一 ...

  6. 分析JVM双亲委派模型的类加载源码 自定义类加载器

    双亲委派模型下,在父类加载器无法加载的情况下再由当前类加载器去加载.具体的实现逻辑在java.util.ClassLoader抽象类的loadClass方法中.在该方法中,先检查是否已经加载过,如果没 ...

  7. 【Java类加载机制】深入类加载器(二)自定义加密、解密类加载器

    类加载器原理 将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区中的运行时数据结构,在堆中生成一个代表这个类的java.lang.Class对象,作为方法区类数据的访问入口. 类加载 ...

  8. 一文理类加载相关知识:类加载器、双亲委派、SPI

    思维导图 类加载的时机 类加载的流程 类从被加载到内存中开始,直到被从内存中卸载为止,它的整个生命周期包括:验证.准备.解析.初始化.使用和卸载7 个阶段. 其中验证.准备.解析 3 个部分统称为连接 ...

  9. java 类加载 双亲委派_Java类加载器和双亲委派机制

    前言 之前详细介绍了Java类的整个加载过程(类加载机制详解).虽然,篇幅较长,但是也不要被内容吓到了,其实每个阶段都可以用一句话来概括. 1)加载:查找并加载类的二进制字节流数据. 2)验证:保证被 ...

最新文章

  1. tcpdump一些选项的使用
  2. Git学习笔记03--git reset
  3. 不知道什么期刊会议是国内计算机行业所承认的好会,顶会?中国计算机协会ccf了解一下!祝你圆梦顶刊、顶会
  4. 用原生JavaScript实现淡入淡出轮播图
  5. PHP开发erp账号登陆问题,浪潮ERP软件E系列创建账套时提示“由于登陆不正确、请重新登陆” | 浪潮888博客...
  6. Spring 3,Spring Web Services 2和LDAP安全
  7. python array函数_Python 中的range()函数与array()函数
  8. 背景色透明,里面内容(图片、文字)不透明
  9. 夺命雷公狗---DEDECMS----14dedecms首页导航条的完成
  10. 李开复:一生换四五次工作在21世纪很正常
  11. 敏捷思维- 架构设计中的方法学(1)
  12. 泰文Unicode编码表及排版规则
  13. jeesite实战(三十六)——非status的其他属性In条件查询
  14. LSM303D磁力计数据读取实验
  15. java多态 -- 猫狗案列
  16. ( 教程 ) 微信公众号做淘宝优惠券自动查券返利机器人怎么设置?
  17. Eason Chan
  18. 微信支付 postman_微信上线新功能,马化腾都在玩!快查查你多少分?
  19. RFX2401C skyworks射频2.4GHZ ZIGBEE/ISM发射/接收RFeIC
  20. linux awk比较大小,linux基础只是之awk命令使用,统计最大长度

热门文章

  1. java连接unix_Java 使用 UnixSocket 调用 Docker API
  2. CDM CDP及传统备份技术对比
  3. 腾讯云认证考试常见问题答疑
  4. Java多线程学习总结(5)——乐观锁和悲观锁的基本概念、实现方式(含实例)、适用场景及常见面试题
  5. Java基础学习总结(142)——以正确的姿势使用Java 8 Optional
  6. Git学习总结(18)——让你成为Git和GitHub大神的20个技巧
  7. Spring学习总结(19)——Spring概念详解
  8. EOS cleos --skip-transaction-signatures 跳过签名
  9. 2018最有影响力的CRM系统排行榜
  10. jQuery获取url地址