首页 > 其他 > 详细

类加载机制

时间:2020-07-16 23:18:00      阅读:52      评论:0      收藏:0      [点我收藏+]

类的加载过程

加载过程可以分为3大阶段:加载 - 链接(验证 -准备 - 解析) - 初始化,如下图:

技术分享图片

加载

这里的加载可以从字面意思理解,主要作用是将外部的 .class 文件转换为二进制数据并加载到JVM的方法区内 , 这里的外部可以指:jar、war、网络中等等

验证

校验 class 文件的格式对否满足JVM规范,不符合规范的将抛出 java.lang.VerifyError 错误

准备

为类变量分配内存,并将其初始化为默认值。此时,实例对象还没有分配内存,所以这些动作是在方法区上进行的。

类变量有两次赋初始值的过程,一次在准备阶段,赋予初始值(也可以是指定值);另外一次在初始化阶段,赋予程序员定义的值。因此,即使程序员没有为类变量赋值也没有关系,它仍然有一个默认的初始值。但局部变量就不一样了,如果没有给它赋初始值,是不能使用的。

解析

将符号引用替换为直接引用的过程,符号引用是一种定义,可以是任何字面上的含义,而直接引用就是直接指向目标的指针、相对偏移量 。 这个阶段大体可以分为:

  • 类或接口的解析
  • 类方法解析
  • 接口方法解析
  • 字段解析

我们经常发生的异常,就与这个阶段有关。

  1. java.lang.NoSuchFieldError 根据继承关系从下往上,找不到相关字段时的报错。
  2. java.lang.IllegalAccessError 字段或者方法,访问权限不具备时的错误。
  3. java.lang.NoSuchMethodError 找不到相关方法时的错误。

解析过程保证了相互引用的完整性,把继承与组合推进到运行时

初始化

进行成员变量的初始化工作

类加载器

类加载器负责类的加载工作,安全、校验等工作都由它来负责。

Bootstrap ClassLoader

它的作用是加载核心类库,也就是 rt.jar、resources.jar、charsets.jar 等。当然这些 jar 包的路径是可以指定的,-Xbootclasspath 参数可以完成指定操作。这个加载器是 C++ 编写的,随着 JVM 启动

Extention ClassLoader

扩展类加载器,主要用于加载 lib/ext 目录下的 jar 包和 .class 文件。同样的,通过系统变量 java.ext.dirs 可以指定这个目录。这个加载器是个 Java 类,继承自 URLClassLoader

App ClassLoader

我们写的 Java 类的默认加载器,有时候也叫作 System ClassLoader。一般用来加载 classpath 下的其他所有 jar 包和 .class 文件,我们写的代码,会首先尝试使用这个类加载器进行加载

Custom ClassLoader

自定义加载器,支持一些个性化的扩展功能

双亲委派机制

在加载一个类的时候,无论子类是否有能力加载,都要先依托父类加载,如果父类没有能力加载那么子类才会加载,这种机制称为双亲委派机制,个人理解双亲就是指:bootstrap、extention classloader。好处是:保证一个类只会被加载一次、并且安全,想象一下如果Object存在于多个,程序会是什么样子。

打破双亲委派的案例

重写loadclass方法即可打破双亲委派机制

Tomcat

Tomcat在加载webapp的时候为了保证多个app的隔离性,加载时是由子类优先加载的,加载不到才会交给父类加载

SPI

ServiceLoader.java 是属于bootstrap classloader 加载的类 , 如果按双清委派模型的话是不可能加载到三方jar中的类的。但是JDK玩了一个小技巧:把加载三方jar的类加载器设置为Thread.currentThread().getContextClassLoader()d , 我们知道线程上下文类加载器默认为application classloader。

类加载机制

原文:https://www.cnblogs.com/lihuamaoa/p/13291417.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!