java入坑之类加载器

一、类加载机制

1.1类加载过程

类加载是Java虚拟机将类的字节码数据从磁盘或网络中读入内存,并转换成在JVM中可以被执行的Java类型的过程。类加载器是Java虚拟机的重要组成部分,负责加载和解析类的字节码,将其转换成Java虚拟机中的类对象,生成加载的类的二进制类数据并存储在方法区中。

类加载过程可以分为以下五个步骤:

1. 加载(Loading):通过类加载器将.class文件字节码读入内存,并生成对应的Class对象,其中包括编译器编译后的代码、静态常量等信息。

2. 验证(Verification):检验字节码文件是否符合Java虚拟机规范,包括是否有正确的魔数、版本信息、常量池中的常量的数据类型是否正确、操作码是否合法等。

3. 准备(Preparation):在内存中为类的静态变量分配内存并赋初始值(数值类型默认为0,对象类型默认为null)。这个过程也包括了给类的静态变量赋予正确的默认值。

4. 解析(Resolution):将类对其他类的引用转换成直接链接,检查类或接口是否在系统中被定义,将符号引用转变为直接引用。

5. 初始化(Initialization):执行类的初始化方法,包括静态变量赋值和静态块调用等操作,即JVM对类进行初始化赋值。如果该类有父类,则按继承层次逐级初始化父类。在执行初始化前,必须保证该类已经完成了加载、验证、准备和解析过程。

 1.2类加载器

类加载器ClassLoader

-负责查找、加载、校验字节码的应用程序

  • java.lang.ClassLoader
  • load(String className)根据名字加载一个类,返回类的实例
  • defineClass((String name,.bytel b,int off,,int len)将一个字节流定义一个类
  • findClass(String name)查找一个类
  • findLoadedClass(String name)在已加载的类中,查找一个类
  • 成员变量ClassLoader paren

Java虚拟机(JVM)中有四个级别的类加载器,分别是:

1. 启动类加载器(Bootstrap ClassLoader):负责加载%JAVA_HOME%/lib目录下的核心类库,如rt.jar等。

2. 扩展类加载器(Extension ClassLoader):负责加载%JAVA_HOME%/lib/ext目录下的扩展类库。

3. 应用程序类加载器(Application ClassLoader):负责加载应用程序classpath下的类。

4. 自定义类加载器(Custom ClassLoader):根据开发者的需要,定制自己的类加载器。

这四个类加载器按照父子关系依次排列,每个类加载器都有自己的加载路径和加载策略。在加载一个类时,它会先委托其父加载器进行加载,如果父加载器无法加载,则由它自己进行加载。如果都无法加载,则会抛出ClassNotFoundException异常。这种父子委托的加载方式被称为“双亲委派模型”。

 1.3双亲委派机制扩展

  • Java严格执行双亲委托机制
  • 类会由最顶层的加载器来加载,如没有,才由下级加载器加载
  • 委托是单向的,确保上层核心的类的正确性
  • 但是上级类加载器所加载的类,无法访问下级类加载器所加载的类
    • 例如,java.lang.String无法访问自定义的一个Test类
    • Java是一个遵循契约设计的程序语言,核心类库提供接口,应用层提供实现
    • 核心类库是BootstrapClassLoader加载
    • 应用层是AppClassLoader加载
    • 典型例子是JDBC和XML Parser等

补充

1.4ServiceLoader

  • 一个服务提供者会在jar包中有META-INF/services目录,里面放一个文件,名字同接口名字。内容的每一行都是接口的一个实现类https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html
  • load方法,可以用当前线程的类加载器来获取某接口的所有实现,当然也都是转为接口类来使用
  • 注意:此服务和ava9模块系统的服务略有差别,但是都能通过ServiceLoader:进行加载

1.5自定义类加载路径


 

自定义加载路径弥补类搜索路径静态的不足,前3个加载的路径都是运行前确定的
Java提供URLClassLoader

  • 程序运行时修改类的加载路径
  • 可从多个来源中加载类 

 1.6自定义类加载器

  • JVM四级类加载器严格遵循从上到下的加载机制
  • 自定义类加载器继承ClassLoader类,可重写loadClass和findClass方法
  • 不同层次的类加载器,加载同名的类,在JVM里面也算两个

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/186888.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nav2 调节纯追踪算法

纯追踪算法 纯追踪基础 The core idea is to find a point on the path in front of the robot and find the linear and angular velocity to help drive towards it. 核心思想是在机器人前方的路径上找到一个点,并找到一个合适的线速度和角速度,以驱…

[量化投资-学习笔记007]Python+TDengine从零开始搭建量化分析平台-布林带

布林带(Bollinger Bands)也称为布林通道、保力加通道,是由约翰布林格(John Bollinger)发明的技术分析指标。布林通道通常被用来确认资产价格波动范围。 布林通道是由三条平滑的曲线组成的趋势线图表,中线为…

leetcode刷题 - SQL - 中等

1. 176. 第二高的薪水 筛选出第二大 查询并返回 Employee 表中第二高的薪水 。如果不存在第二高的薪水,查询应该返回 null(Pandas 则返回 None) 。查询结果如下例所示。 666中等的第一题就上强度 强行解法 select max(salary) as SecondHighestSalary from Emp…

深入解析 Redis 分布式锁原理

一、实现原理 1.1 基本原理 JDK 原生的锁可以让不同线程之间以互斥的方式来访问共享资源,但如果想要在不同进程之间以互斥的方式来访问共享资源,JDK 原生的锁就无能为力了。此时可以使用 Redis 来实现分布式锁。 Redis 实现分布式锁的核心命令如下&am…

【Git】如何安装git,项目中使用git上传到远程仓库,使用git中对多人使用出现的版本问题的解决

前言: 一,Git的介绍,安装,与SVN的对比 1.1Git的介绍 Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控…

ubuntu下Anaconda环境安装GPU的pytorch(docker镜像)

实验室需要给每个人分配docker的container环境,为了节省系统的空间,打算把anaconda和深度学习的开发环境配置好拉取镜像以省时间。 基础环境配置 apt更新了清华源 安装了基础环境 gcc vim Linux文本编辑库 openssh-server ssh远程连接库 net-tools 包含…

关于Android Studio中开发Flutter配置

配置系统环境变量:path下 ,flutter的bin目录下 File->Settings->Languages&Frameworks->FlutterFile->Settings->Languages&Frameworks->DartFile->Settings->Languages&Frameworks->Android SDK 确认是…

接口开发之使用C#插件Quartz.Net定时执行CMD任务工具

C#制作定时任务工具执行CMD命令 概要准备知识点实现原理thinkphp配置winform执行CMD命令读取ini配置文件定时任务Quartz.Net 完整代码Job.csIniFunc.csForm1.csconfig.ini简易定时任务工具雏形 概要 很多时候写接口上线后还会遇到很多修改,类似JAVA,C#,delphi制作的…

面试字节测开岗失败后,被面试官在朋友圈吐槽了......(心累)

在和朋友吃夜宵的时候,朋友向我吐槽说自己在参加某大厂测试面试的时候被面试官怼得哑口无言,场面让他一度十分尴尬 印象最深的就是下面几个问题: 根据你以前的工作经验和学习到的测试技术,说说你对质量保证的理解? 非…

动态规划-构建乘积数组

** 描述 给定一个数组 A[0,1,…,n-1] ,请构建一个数组 B[0,1,…,n-1] ,其中 B 的元素 B[i]A[0]A[1]…*A[i-1]A[i1]…*A[n-1](除 A[i] 以外的全部元素的的乘积)。程序中不能使用除法。(注意:规定 B[0] A[1] * A[2] * … * A[n-1…

GeoGebra:数学动画制作工具重磅来袭

【线性代数】线性代数可视化工具:manim manim是之前我跟大家分享的一个线性代数动画制作工具。 但我之前的描述有些许偏差,这里要更正一下,manim不仅限于制作线性代数动画,也可以制作数学其他学科的动画,例如微积分&…

[极客大挑战 2019]BuyFlag 1(两种解法)

题目环境: FLAG NEED YOUR 100000000 MONEY flag需要你的100000000元 F12瞅瞅源代码: if (isset($_POST[password])){ $password $_POST[password]; if (is_numeric($password)) { echo "password cant be number" } elseif ($pas…

理解MySQL的日志 Redo、Undo

理解MySQL的Redo日志和Undo日志 1、MySQL 日志文件解决的问题2、redo 日志2.1、redo log 的组成2.2、redo log 刷盘策略2.3、MySQL 的 redo log解决了哪些问题 3、undo 日志3.1、undo 日志作用3.2、undo log 的类型3.3、undo log 的生命周期3.4、事务回滚相关的几个隐藏字段 1、…

使用easyui前端框架快速构建一个crud应用

本篇文章将会详细介绍jquery easyui前端框架的使用,通过创建一个crud应用来带大家快速掌握easyui的使用。 easyui是博主最喜欢的前端框架,没有之一,因为它提供了多种主题,而且有圆润的各种组件。 目录 一、快速开始 二、准备工作…

JS逆向爬虫---请求参数加密③【比特币交易爬虫】

查询参数确定 t无加密 请求头参数加密 X-Apikey参数加密确定 X-Apikey逆向 const API_KEY "a2c903cc-b31e-4547-9299-b6d07b7631ab" function encryptApiKey(){ var t API_KEY, e t.split(""), n e.splice(0, 8);return t e.concat(n).join("&…

利用Ansible实现批量Linux服务器安全配置

1.摘要 在上一篇<<初步利用Ansible实现批量服务器自动化管理>>文章中, 我初步实现了通过编写清单和剧本来实现多台服务器的自动化管理,在本章节中, 我将利用Ansible的剧本来实现更实用、更复杂一点的功能, 主要功能包括三个:1.同时在三台服务器中增加IP访问控制,只…

万宾科技智能井盖,实现对井盖的监测

随着人工智能和物联网技术的不断变化&#xff0c;各种适用于市政府提高管理能力和公共服务水平的高科技产品不断更新。在道路基础设施建设过程中&#xff0c;智能井盖传感器的出现时刻保护着城市地下生命线&#xff0c;而且可以对地下水道井盖进行实时的监测并完成数据上传等工…

Excel下拉填充时,如何使得数字不递增?

问题描述&#xff1a;Excel下拉填充时&#xff0c;如何使得数字不递增&#xff1f; 解决办法&#xff1a;先下拉填充数据之后&#xff0c;看到最后一个单元格的右下角有个填充设置的符号&#xff0c;右键选择复制单元格即可。其中这里的填充序列就是递增数字的操作。

使用Pytorch的一些小细节(一)

文章目录 前言数据结构-张量max函数索引函数赋值函数拼接函数 前言 由于不经常动手写代码&#xff0c;所以对于python语言中的常见数据结构的用法也不是很熟悉&#xff0c;对于pytorch中的数据结构就更加不熟悉了。之前的代码基础是基于C语言的&#xff0c;属性都是自己定义&a…

Selenium是什么,带你了解自动化测试的神奇之处

一、使用测试工具 工欲善其事&#xff0c;必先利其器。在开始具体的自动化测试之前&#xff0c;我们需要做好更多的准备&#xff0c;包括以下几个方面&#xff1a; 认识自动化测试 准备自动化测试工具 使用有效的方式 针对具体的测试对象 接下来的第一部分内容&#xff0c;我…