类加载机制

一个类的整个生命周期如下:

在这里插入图片描述

.class文件需要加载进虚拟机中,才能运行和使用这些.class文件。加载的过程,就是把.class文件加载到内存,根据.class文件在内存中创建Class对象,并对数据进行校验、解析、初始化,最终形成虚拟机可以直接使用的Java类型,这也是Java虚拟机的类加载机制。

类加载具体分为3个步骤,如下:

  1. 加载:查找字节码,并在内存中创建一个Class对象

  2. 连接:验证类中的字节码,为新对象分配内存,并将变量的值设置为系统默认的初始值。

  3. 初始化:按照程序员的意愿进行初始化。

类加载是由类加载器完成的,选择用哪个类加载器来加载类是使用双亲委派机制来确定的。

小纸条

数组类型不通过类加载器创建,它由 Java 虚拟机直接创建。

1. 类加载过程

上图中黄色背景中的部分是类加载所需要进行的操作。

2. 什么时候会加载类

第一次使用到类的时候(比如创建类的实例、要加载子类前需要先加载父类、用到类的静态方法等)会加载类,不使用不会提前加载。

3. 用什么加载类?-类加载器

JVM中内置了三个重要的 ClassLoader,除了 BootstrapClassLoader其他类加载器均由 Java 实现且全部继承自java.lang.ClassLoader

  1. BootstrapClassLoader(启动类加载器) :最顶层的加载类,由 C++实现,负责加载 %JAVA_HOME%/lib目录下的 jar 包和类或者被 -Xbootclasspath参数指定的路径中的所有类。

  2. ExtensionClassLoader(扩展类加载器) :主要负责加载 %JRE_HOME%/lib/ext 目录下的jar 包和类,或被 java.ext.dirs 系统变量所指定的路径下的 jar 包。

  3. AppClassLoader(应用程序类加载器) :面向我们用户的加载器,负责加载当前应用 classpath 下的所有 jar 包和类。

在这里插入图片描述

4. 选择类加载器的规则-双亲委派机制

4.1 双亲委派模型

每一个类都有一个对应它的类加载器。系统中的类加载器在协同工作的时候会默认使用 双亲委派模型

  1. 判断。在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载。

  2. 向上委派。加载的时候,首先会把该请求委派给父类加载器的 loadClass() 处理,因此所有的请求最终都应该传送到顶层的启动类加载器 BootstrapClassLoader 中。

  3. 向下加载。当父类加载器无法处理时,才由自己来处理。当父类加载器为 null 时,会使用启动类加载器 BootstrapClassLoader 作为父类加载器。

在这里插入图片描述

4.2 好处

  • 防止加载同一个 .class 文件

  • 保证核心 API不被篡改

双亲委派模型保证了 Java程序的稳定运行,可以防止加载同一个 .class 文件,避免类的重复加载。也保证了 Java核心 API 不被篡改

小纸条

如何判断两个 class 是否相同??

JVM在判定两个class是否相同时,不仅要判断两个类名是否相同,而且要判断是否由同一个类加载器实例加载的

4.3 如何打破双亲委派

如果我们想自己写一个类加载器来加载这个类,而不是通过系统默认的类加载器来加载的话。就要自定义一个类加载器,重写loadClass()。双亲委派机制是通过类加载器 ClassLoader 中的 loadClass() 实现的。

  • 在自定义类加载器的时候,如果不想打破双亲委派,只重写 findClass()

  • 如果想打破双亲委派,重写 loadClass()

典型的打破双亲委派的框架和中间件是 Tomcatosgi

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值