浅谈类加载机制

类加载

概念:

当JVM第一次使用一个类的时候,通过classPath(类路径)找到对应的 .class 文件,从 .class文件中读取该类的信息

(包、类名、父类、属性、成员方法、构造方法等),读取之后将信息存储在JVM内存中,一个类只进行一次类加载。

在这里插入图片描述

类的生命周期:

在这里插入图片描述

类加载过程:

在这里插入图片描述

加载到初始化都是在程序的与运行期间完成的。验证,准备,解析也叫连接过程,Java的特性是依赖在运行期动态加载和动态连接。

加载

”加载“是”类加机制”的第一个过程,在加载阶段,虚拟机主要完成三件事:

(1)通过一个类的全限定名来获取其定义的二进制字节流

(2)将这个字节流所代表的的静态存储结构转化为方法区的运行时数据结构

(3)在堆中生成一个代表这个类的java.lang.Class对象,作为方法区中这些数据的访问入口。

连接-验证

目的在于确保class文件的字节流中包含信息符合当前虚拟机要求,不会危害虚拟机自身的安全,

根据2011年发布的<java虚拟机规范>的要求,验证阶段大致需要一下四个阶段来验证

主要包括四种验证:文件格式的验证,元数据的验证,字节码验证,符号引用验证。

  • 文件格式验证,该阶段主要在字节流转化为方法区中的运行时数据时,负责检查字节流是否符合Class文件的规范,保证其可以正确的被解析并存储于方法区中。
  • 元数据验证,确保Class的语义描述符合Java的Class规范。如:该Class是否有父类、是否错误继承了final类、是否一个合法的抽象类等。
  • 字节码验证,通过分析数据流和控制流,确保程序语义符合逻辑。如:验证类型转换是合法的。
  • 符号引用验证,发生于符号引用转换为直接引用的时候(转换发生在解析阶段)。如:验证引用的类、成员变量、方法的是否可以被访问,当前类是否存在相应的方法、成员等。
连接-准备

在准备阶段,虚拟机会在方法区中为Class分配内存,并设置static成员变量的初始值为默认值。注意这里仅仅会为static变量分配内存(static变量在方法区中),并且初始化static变量的值为其所属类型的默认值。如:int类型初始化为0,引用类型初始化为null。即使声明了这样一个static变量:

public static int a = 123;

在准备阶段后,a在内存中的值仍然是0, 赋值123这个操作会在中初始化阶段执行,因此在初始化阶段产生了对应的Class对象之后a的值才是123 。为类变量(static修饰的字段变量)分配内存并且设置该类变量的初始值,(如static int i = 5 这里只是将 i 赋值为0,在初始化的阶段再把 i 赋值为5),这里不包含final修饰的static ,因为final在编译的时候就已经分配了。这里不会为实例变量分配初始化,类变量会分配在方法区中,实例变量会随着对象分配到Java堆中。

连接-解析

常量(用final修饰的成员变量表示常量,值一旦给定就无法改变!)

解析阶段,虚拟机会将常量池中的符号引用替换为直接引用,解析主要针对的是类、接口、方法、成员变量等符号引用。在转换成直接引用后,会触发校验阶段的符号引用验证,验证转换之后的直接引用是否能找到对应的类、方法、成员变量等。

初始化

初始化阶段,才真正开始执行类中定义的java程序代码

这里是类记载的最后阶段,如果该类具有父类就进行对父类进行初始化,执行其静态初始化器(静态代码块)和静态初始化成员变量。(前面已经对static 初始化了默认值,这里我们对它进行赋值,成员变量也将被初始化)

类加载时机:

①第一次创建该类对象:先进行类加载,在完成对象的创建

②第一次使用该类的静态成员(静态属性和静态方法)

③子类的类加载会导致其父类先进行类加载

④使用java.lang.reflect包的方法对类进行反射调用的时候

⑤当虚拟机启动时,用户指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。

双亲委派机制:

在这里插入图片描述

首先需要知道的是,java类加载遵循一个机制——Parents Delegation Model(双亲委派模型)
双亲委派机制:就是某个特定的类加载器在接收到加载类的请求时,除非显示的要求使用某一个类加载器,都会将加载任务委托给父类加载器,父类加载器又将加载任务继续向上委托,知道最终父类加载器,如果最终父类加载器可以完成此类的加载任务,就由其完成加载,如果不行就依次向下传递任务,由其子类加载器进行加载。

双亲委派机制有什么好处?

1、 出于安全考虑,这么做保证了java核心库的安全性,确保基础类永远都是由java提供的跟加载器来加载。
2、 可以避免重复加载,当父加载器已经加载了该类后,子类就没有必要再加载一次。
从以上两点出发,如果有人恶意篡改了基础类的代码(例如:java.lang.string)那他自己定义的java.lang.string将永远不会被加载进来,因为原始的String类已经在启动的时候就被加载进来了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值