类加载和类加载器
部分资料来自黑马程序员和JavaGuide
1 类加载
1.1 什么是类加载/类初始化
注意:
- 类加载的过程:加载-连接-初始化
- 连接的过程:验证-准备-解析
- 加载阶段和连接阶段的部分内容是交叉进行的
- 【面试】简述 加载 过程的工作:
4.1 通过全类名(某个文件在项目中的位置 包名.类名)获取 定义此类的 二进制字节流
4.2 将字节流所代表的 静态存储结构 转化为 方法区的 运行时数据结构
4.3 在内存中生成一个代表该类的Class对象————作为 方法区 这些数据的访问入口 - 加载和初始化都是懒惰执行(不到万不得已不执行)
- static变量是在
连接
部分分配变量,设置默认值,在初始化
阶段进行 非final静态变量的赋值。 而final变量是在连接
过程中赋值的。
简单来说,加载阶段的工作就是把.class文件读入内存,让生成一个Class对象。
1.2 类初始化的步骤和时机
2 类加载器 ClassLoader
2.1 类加载器的作用和JVM的类加载机制
2.2 ClassLoader
-
有哪些内置类加载器:
-
看看ClassLoader的文档:
-
【面试】你知道哪些类加载器?
我们上面提过的那三个JVM内置的类加载器需要我们掌握。
-
首先呢,第一个是
启动类加载器
,BootstrapClassLoader。它是最顶层的加载类,由C++实现,负责加载lib下的jar包和类。它没有父加载器。 -
然后,是
扩展类加载器
,ExtensionClassLoader(之所以和2.2的叫法不同,是java9模块化之后,对classloader有所改造,其中一点就是将extensionClassLoader改为PlatformClassLoader,另外模块化之后,对应的classloader加载各自对应的模块,不过很多开发使用的还是1.8的版本,这个可以作为了解一下,你可以还是按照extension来说),它负责加载lib/ext目录下的jar包和类。 -
最后,是
应用程序类加载器
,AppClassLoader,(和2.2提到的SystemClassLoader,实际上也是一个东西,看他们的职责就能了解。而在jdk1.9的版本中,文档明确指出了系统类加载器也被叫做application class loader,所以你怎么说都不算是错误的)它是面向用户的加载器,负责加载Classpath下的所有jar包和类。
ApplicationClassLoader的父加载器是-----> ExtensionClassLoader,ExtensionClassLoader的父加载器是 BootStrapClassLoader, BootStrapClassLoader的父加载器是---->null。他们之间的父子关系不是通过继承来实现的,而是通过优先级来决定的。
2.3 【面试】双亲委派模型 - Parent-delegaton model
实际上这个翻译是有歧义的,直接机翻了。这个双亲让人理解很困难。可以直接理解为 父委托机制。这个我们在上面的JVM类加载机制中已经说了,也可以说是 父类委托,双亲委派模型,本质上就是JVM的类加载机制的一种。
前提,
人人都有
,每一个类都有一个对应它的类加载器。
首先,
先判有无
,在 【类加载的时机】,系统会判断类是否被加载过。已加载过的内会直接返回,否则才会尝试加载。
然后,委托给父
,加载的时候,会把该请求 委派给 其父类加载器的 loadClass()处理。
接着,自底向上委托
,这些请求 被一层层向上委派,最终都对到达 最顶层,也就是 启动类加载器 BootstrapClassLoader中。
最终,自顶向下加载
,当父类加载器无法处理时,一级级往下尝试加载,自己处理。