千家信息网

java类加载过程分为哪些步骤

发表于:2025-01-30 作者:千家信息网编辑
千家信息网最后更新 2025年01月30日,本篇内容介绍了"java类加载过程分为哪些步骤"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一般来说
千家信息网最后更新 2025年01月30日java类加载过程分为哪些步骤

本篇内容介绍了"java类加载过程分为哪些步骤"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一般来说,我们把Java的类加载过程分为三个主要步骤:加载、链接、初始化
加载阶段(Loading)

它是Java将字节码数据从不同的数据源读取到JVM中,并映射为JVM认可的数据结构(Class对象)。这里的数据源可能是各种各样的形态,如jar文件、class文件,甚至是网络数据源等。如果输入数据不是ClassFile的结构,则会抛出ClassFormatError。
加载阶段是用户参与的阶段,我们可以自定义类加载器,去实现自己的类加载过程。

链接阶段(Linking)

这是核心的步骤,简单说是把原始的类定义信息平滑地转化入JVM运行的过程中。这里可进一步细分为三个步骤:

  • 验证(Verification),这是虚拟机安全的重要保障,JVM需要核检字节信息是符合Java虚拟机规范的,否则就被认为是VerifyError。这样就防止了恶意信息或者不合规的信息危害JVM的运行。验证阶段有可能触发更多class的加载。

  • 准备(Preparation),创建类或接口中的静态变量,并初始化静态变量的初始值。但这里的"初始化"和下面的显式初始化阶段是有区别的,侧重点在于分配所需要的内存空间,不会去执行更进一步的JVM指令。

  • 解析(Resolution),在这一步会将常量池中的符号引用(symbolic reference)替换为直接引用。在Java虚拟机规范中,详细介绍了类、接口、方法和字段等各个方面的解析。

初始化(Initialization)

这一步真正去执行类初始化的代码逻辑,包括静态字段复制的动作,以及执行类定义中的静态初始化块内的逻辑。编译器在编译阶段就会把这部分逻辑整理好,父类型的初始化逻辑优先于当前类型的逻辑。

Java 8之前的类加载器

启动类加载器(Bootstrap Class-Loader),加载jre/lib下面的jar文件,如rt.jar。它是个超级公民,即使是在开启了Security Manager的时候,JDK仍赋予了它加载的程序AllPermission。

对于做底层开发的工程师,有的时候可能不得不去试图修改JDK的基础代码,也就是通常意义上的核心类库,我们可以使用下面的命令行参数。

# 指定新的 bootclasspath,替换 java.* 包的内部实现
java -Xbootclasspath: your_App

# a 意味着 append,将指定目录添加到 bootclasspath 后面
java -Xbootclasspath/a: your_App

# p 意味着 prepend,将指定目录添加到 bootclasspath 前面
java -Xbootclasspath/p: your_App

用法其实很易懂,例如,使用最常见的"/p",既然是前置,就有机会替换个别基础类的实现。

我们一般可以使用下面方法获取父加载器,但是在通常的JDK/JRE实现中,扩展类加载器getParent()都只能返回null。

public final ClassLoader getParent()

扩展类加载器(Extension or Ext Class-Loader),负责加载我们放到jre/lib/ext目录下面的jar包,这就是所谓的extension机制。该目录也可以通过设置"java.ext.dirs"来覆盖

java -Djava.ext.dirs=your_ext_dir HelloWorld

应用类加载器(Application or App Class-Loader),就是加载我们最熟悉的classpath的内容。这里有一个容易混淆的概念,系统(System)类加载器,通常来说,其默认就是JDK內建的应用类加载器,但是它同样是可能修改的,比如:

java -Djava.system.class.loader=com.yourcorp.YourClassLoader HelloWorld

如果我们指定了这个参数,JDK內建的应用类加载器就会成为定制加载器的父亲,这种方式通常用在类似需要改变双亲委派模式的场景。

具体参考下图:

双亲委派模型

谈到类加载一个躲不开的话题就是"双亲委派模型",简单说就是当类加载器(Class-Loader)试图加载某个类型的时候,除非父加载器找不到相应的类型,否则尽量将这个任务代理给当前加载器的父加载器去做。

参考上面这个结构图就很容易理解了。试想,如果不同类加载器都自己加载需要的某个类型,那么就会出现多次重复加载,完全是种浪费。

通常类加载器机制有三个基本特征:

  • 双亲委派模型。但不是所有类加载都遵守这个模型,有的时候,启动类加载器所加载的类型,是可能要加载用户代码的。比如JDK内部的ServiceProvider/ServiceLoader机制,用户可以在标准API框架上,提供自己的实现,JDK也需要提供些默认的参考实现。例如,Java中JNDI、JDBC、文件系统、Cipher等很多方面,都是利用的这种机制,这种情况就不会用双亲委派模型去加载,而是利用所谓的上下文加载器。

  • 可见性。子加载器可以访问父加载器加载的类型,但是反过来是不允许的。不然,因为缺少必要的隔离,我们就没有办法利用类加载器去实现容器的逻辑。

  • 单一性。由于父加载器的类型对于子加载器是可见的,所以父加载器中加载过的类型,就不会在子加载器中重复加载。但是注意,类加载器"邻居"间,同一类型仍然可以被加载多次,因为互相不可见。

"java类加载过程分为哪些步骤"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

类型 阶段 过程 数据 逻辑 步骤 双亲 就是 模型 委派 信息 文件 时候 机制 目录 静态 面的 三个 代码 内容 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 保融科技软件开发笔试题 英特尔x58服务器主板 医药前沿被什么数据库收录 福昕软件开发有限公司估值 erp系统对服务器要求高么 怎么实现多层数据库技术 银行软件开发工资最高的 sql数据库fk是什么意思 acfun服务器地址 碧蓝航线怎么删除服务器上的角色 华为全球最大数据库 ssh框架的数据库连接 社会该怎么对网络安全问题 泰兴小型网络技术诚信合作 事务型数据库性能专项评测证书 网络安全风险博弈模型 做网络安全需要汇编吗 如何戒色软件开发 网络安全志愿者注册 静安区网络软件开发服务报价表 明光威力软件开发技术采购信息 六年级网络安全征文500 网络安全手抄报写字素材 网络安全的手抄报文字框怎么写 网络安全属于新媒体吗 大专才有计算机网络技术是吗 计算机三级网络技术自治系统 u 盘损坏怎么导出数据库 萧山计算机网络技术招工 网盘单独数据库
0