当前位置: 首页 > news >正文

通俗易懂:什么是 Java 类加载?

文章目录

      • 类加载过程的三个阶段
      • 一个简单的案例:类加载的工作原理
      • 使用这个类
      • 类加载的顺序
      • 类加载的特点
      • 类加载的好处
      • 总结
      • 推荐阅读文章

在 Java 中, 类加载是一种将我们写的 Java 类文件加载到内存中的过程,让 JVM(Java 虚拟机)可以识别和执行它们。Java 类加载是一个神奇的过程,因为它让我们写的代码从“静态”的文件,变成了“动态”可执行的程序。

要理解类加载,我们可以从三个主要阶段来了解它们的作用:加载连接初始化


类加载过程的三个阶段

  1. 加载(Loading)

    • 在这个阶段,JVM 通过类加载器(ClassLoader)找到我们写的 .class 文件,把它们的字节码读进内存。
    • 这个过程可以想象成打开一本书,把它从书架上取出来,放到桌子上开始阅读。
  2. 连接(Linking)

    • 连接过程有三个小步骤:验证准备解析
      • 验证:JVM 检查类文件的格式是否正确,确保没有错误的字节码。
      • 准备:JVM 为类的变量分配内存空间,并初始化默认值。
      • 解析:JVM 把类中的符号引用(如方法名、变量名)转换成直接引用,让它们可以被实际调用。
    • 类似于读书时理解内容的逻辑,比如检查章节标题和内容是不是一致。
  3. 初始化(Initialization)

    • 这是类加载的最后一步。JVM 会执行类中的静态初始化代码静态变量的赋值操作。
    • 可以理解为在正式读书前标注关键内容,为阅读做准备。

一个简单的案例:类加载的工作原理

假设我们有一个简单的类 HelloWorld

public class HelloWorld {static String message = "Hello, Java!";static {System.out.println("HelloWorld 类已被加载!");}public void sayHello() {System.out.println(message);}
}

这个 HelloWorld 类有一个静态变量 message 和一个静态代码块。静态代码块中的 System.out.println() 会在类加载时执行。

使用这个类

我们编写一个 Main 类来使用 HelloWorld

public class Main {public static void main(String[] args) {HelloWorld hello = new HelloWorld(); // 第一次使用 HelloWorld 类hello.sayHello(); // 调用方法}
}

当我们运行 Main 类时,会看到以下输出:

HelloWorld 类已被加载!
Hello, Java!

类加载的顺序

让我们分解一下这个过程发生了什么:

  1. 加载

    • Main 类中第一次创建 HelloWorld 对象时,JVM 发现 HelloWorld 类还没有被加载。
    • 类加载器加载 HelloWorld.class 文件,将其加载进内存。
  2. 连接

    • JVM 连接 HelloWorld 类,检查它的格式(验证)、为 message 分配内存并设置默认值(准备),然后解析类中的方法和变量引用。
  3. 初始化

    • JVM 执行 HelloWorld 类的静态代码块 System.out.println("HelloWorld 类已被加载!");,这就是我们看到的第一行输出。
    • 同时,把 message 静态变量赋值为 "Hello, Java!"

类加载的特点

  1. 延迟加载(Lazy Loading)

    • Java 类的加载是延迟的,JVM 在真正使用一个类时才会加载它。这就是为什么 HelloWorld 类的静态代码块在我们调用 new HelloWorld() 时才会执行。
  2. 类加载器(ClassLoader)

    • Java 中有三种类加载器,分别是启动类加载器扩展类加载器应用类加载器
      • 启动类加载器负责加载核心 Java 类库,比如 java.lang.String
      • 扩展类加载器负责加载一些扩展类。
      • 应用类加载器负责加载应用程序中定义的类,比如我们的 HelloWorld 类。
  3. 单一实例

    • 一个类在整个应用中只会被加载一次。如果我们多次创建 HelloWorld 对象,静态代码块不会重复执行,这就是类加载的“单一实例”特性。

类加载的好处

类加载过程是 Java 的一个核心优势:

  • 安全性:加载过程中的验证步骤帮助确保类文件不会有错误的字节码,保护程序不被恶意代码破坏。
  • 效率:Java 只在需要时加载类,减少了内存占用。
  • 可扩展性:类加载器机制允许动态加载类,比如在 Java Web 应用中可以动态加载第三方库。

总结

Java 类加载是一个将 .class 文件加载到内存的过程,通过加载、连接和初始化的三个步骤来确保类能够被正确地使用。类加载机制保证了代码的安全性、可维护性和内存管理的效率。理解类加载,可以帮助我们更好地使用 Java 的类和对象,让代码运行得更加流畅!

希望这个解释让你对 Java 类加载有了更清晰的认识!

推荐阅读文章

  • 由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)

  • 如何理解 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的联系

  • HTTP、HTTPS、Cookie 和 Session 之间的关系

  • 什么是 Cookie?简单介绍与使用方法

  • 什么是 Session?如何应用?

  • 使用 Spring 框架构建 MVC 应用程序:初学者教程

  • 有缺陷的 Java 代码:Java 开发人员最常犯的 10 大错误

  • 如何理解应用 Java 多线程与并发编程?

  • 把握Java泛型的艺术:协变、逆变与不可变性一网打尽

  • Java Spring 中常用的 @PostConstruct 注解使用总结

  • 如何理解线程安全这个概念?

  • 理解 Java 桥接方法

  • Spring 整合嵌入式 Tomcat 容器

  • Tomcat 如何加载 SpringMVC 组件

  • “在什么情况下类需要实现 Serializable,什么情况下又不需要(一)?”

  • “避免序列化灾难:掌握实现 Serializable 的真相!(二)”

  • 如何自定义一个自己的 Spring Boot Starter 组件(从入门到实践)

  • 解密 Redis:如何通过 IO 多路复用征服高并发挑战!

  • 线程 vs 虚拟线程:深入理解及区别

  • 深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别

  • 10大程序员提升代码优雅度的必杀技,瞬间让你成为团队宠儿!

  • “打破重复代码的魔咒:使用 Function 接口在 Java 8 中实现优雅重构!”

  • Java 中消除 If-else 技巧总结

  • 线程池的核心参数配置(仅供参考)

  • 【人工智能】聊聊Transformer,深度学习的一股清流(13)

  • Java 枚举的几个常用技巧,你可以试着用用

  • 由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)

  • 如何理解 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的联系

  • HTTP、HTTPS、Cookie 和 Session 之间的关系

  • 使用 Spring 框架构建 MVC 应用程序:初学者教程

  • 有缺陷的 Java 代码:Java 开发人员最常犯的 10 大错误

  • Java Spring 中常用的 @PostConstruct 注解使用总结

  • 线程 vs 虚拟线程:深入理解及区别

  • 深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别

  • 10大程序员提升代码优雅度的必杀技,瞬间让你成为团队宠儿!

  • 探索 Lombok 的 @Builder 和 @SuperBuilder:避坑指南(一)

  • 为什么用了 @Builder 反而报错?深入理解 Lombok 的“暗坑”与解决方案(二)

相关文章:

通俗易懂:什么是 Java 类加载?

文章目录 类加载过程的三个阶段一个简单的案例:类加载的工作原理使用这个类类加载的顺序类加载的特点类加载的好处总结推荐阅读文章 在 Java 中, 类加载是一种将我们写的 Java 类文件加载到内存中的过程,让 JVM(Java 虚拟机&…...

Dijkstra 算法的实现方案

下面是一个基于 Dijkstra 算法的实现方案,能够在 DEM(数字高程模型)数据上进行寻路,并满足以下需求: 使用 Qt C++ 编写; 规避 DEM 中的障碍物; 支持指定起点和终点; 使用 GDAL 库读取 DEM 文件; 输出路径到 TXT 文件; 输出的坐标为地理坐标(例如经纬度),而不是像…...

OpenGL 进阶系列07 - 阴影贴图(shadowmap )

一:概述: 在 OpenGL 中,Shadow Mapping(阴影贴图)是一种常用的实时阴影技术,用于渲染物体的阴影效果。这种方法通过生成光源视角下的深度贴图,再在场景渲染时使用它来判断物体是否被遮挡,从而实现阴影效果。下面是实现 Shadow Mapping 的基本步骤和相关知识。 二:绘制…...

【CAN介绍】【第一篇章】

1. CAN简介 • CAN 总线( Controller Area Network Bus )控制器局域网总线 • CAN 总线是由 BOSCH 公司开发的一种简洁易用、传输速度快、易扩展、可靠性高的串行通信总线,广泛应用于汽车、嵌入式、工业控制等领域 • CAN 总线特征&#xff1…...

【统计子矩阵——部分前缀和+双指针】

题目 代码 #include <bits/stdc.h> using namespace std; typedef long long ll; const int N 510; int s[N][N]; int main() {ios::sync_with_stdio(0);cin.tie(0);int n, m, k;cin >> n >> m >> k;for(int i 1; i < n; i)for(int j 1; j <…...

用正则表达式检查是IP否为内网地址

用正则表达式检查是ip否为内网地址 PHP function isIntranet($ip) {/* IPV4内网地址A 类10.0.0.0&#xff5e;10.255.255.255B 类172.16.0.0&#xff5e;172.31.255.255C 类192.168.0.0&#xff5e;192.168.255.255*/// 检查是否为 IPv4 内网地址if (preg_match(/^10\./, $ip…...

Leetcode刷题笔记14

136. 只出现一次的数字 136. 只出现一次的数字 - 力扣&#xff08;LeetCode&#xff09; 核心思想&#xff1a;按位异或运算 利用按位异或运算的性质来解决这个问题&#xff1a; 异或运算的性质&#xff1a; a ^ a 0&#xff1a;相同的数异或结果为0。 a ^ 0 a&#xff1a…...

PHP图书绘本借阅管理系统小程序源码

&#x1f4da; 图书绘本借阅管理系统&#xff1a;打造孩子的阅读乐园 &#x1f4da; &#x1f3f7;️ 引言&#xff1a;为什么我们需要图书绘本借阅管理系统&#xff1f; 在孩子的成长旅程中&#xff0c;阅读是不可或缺的一部分。然而&#xff0c;面对琳琅满目的图书和绘本&a…...

【JavaWeb】JavaWeb入门之XML详解

目录 1.XML介绍 1.1.XML概述 1.1.1.什么是XML 1.1.2.XML的作用 1.1.3.XML与HTML的比较 1.1.4.XML和properties&#xff08;属性文件&#xff09;比较 1.1.5.W3C组织 1.2.XML语法概述 1.2.1.XML文档展示 1.2.2.XML文档的组成部分 1.3.XML文档声明 1.3.1.什么是XML文…...

JS手写-this绑定实现

在 JavaScript 中&#xff0c;bind、call 和 apply 方法都可以用来改变函数的 this 指向。下面我们将分别实现这些方法的简单版本。 1. 实现 bind bind 方法创建一个新的函数&#xff0c;在调用时设置 this 值&#xff0c;并返回这个新的函数。 Function.prototype.myBind …...

【时间之外】IT人求职和创业应知【31】

目录 新闻一&#xff1a;2024年“秦创原沣东杯”陕西省科技工作者创新创业大赛颁奖仪式暨沣东新城机器人产业发展大会盛大启幕 新闻二&#xff1a;声网CEO赵斌&#xff1a;RTE将成为生成式AI时代AI Infra的关键部分 新闻三&#xff1a;“5G工业互联网”融合应用试点城市名单…...

如何使用ffmpeg命令行进行录屏

录屏软件&#xff0c;我们去网上下载&#xff0c;发现有很多软件都是要收费的&#xff01;但是录屏功能很难做吗&#xff1f;为啥都需要收费呢&#xff1f; 于是我整了个小demo&#xff0c;用于实现基础的屏幕录制功能。 思路很简单&#xff0c;考虑到 FFMpeg.exe是一个非常成…...

ODOO学习笔记(8):模块化架构的优势

灵活性与可定制性 业务流程适配&#xff1a;企业的业务流程往往因行业、规模和管理方式等因素而各不相同。Odoo的模块化架构允许企业根据自身的具体业务流程&#xff0c;选择和组合不同的模块。例如&#xff0c;一家制造企业可以启用采购、库存、生产和销售模块&#xff0c;并通…...

数字IC后端实现之Innovus specifyCellEdgeSpacing和ICC2 set_placement_spacing_rule的应用

昨天帮助社区IC训练营学员远程协助解决一个Calibre DRC案例。通过这个DRC Violation向大家分享下Innovus和ICC2中如何批量约束cell的spacing rule。 数字IC后端手把手实战教程 | Innovus verify_drc VIA1 DRC Violation解析及脚本自动化修复方案 下图所示为T12nm A55项目的Ca…...

每日小练:Day2

1.乒乓球筐 题目链接&#xff1a;乒乓球筐__牛客网 题目描述&#xff1a; 这道题主要考察B盒是不是A盒的子集&#xff0c;我们可以通过哈希表来做 单哈希表 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public stat…...

ubuntu 安装kafka-eagle

上传压缩包 kafka-eagle-bin-2.0.8.tar.gz 到集群 /root/efak 目录 cd /root/efak tar -zxvf kafka-eagle-bin-2.0.8.tar.gz cd /root/efak/kafka-eagle-bin-2.0.8 mkdir /root/efakmodule tar -zxvf efak-web-2.0.8-bin.tar.gz -C /root/efakmodule/ mv /root/efakmodule/efak…...

深入理解指针

在初步了解了指针的用法之后&#xff0c;我们可以想一想&#xff0c;既然一个变量有地址&#xff0c;而且在上一篇文章中我们知道了一个数组也有地址&#xff0c;那么函数、字符串这些东西有没有地址呢&#xff1f;如果有&#xff0c;那这些地址有什么用&#xff1f;我们又要怎…...

自动驾驶合集(更新中)

文章目录 车辆模型控制路径规划 车辆模型 车辆模型基础合集 控制 控制合集 路径规划 规划合集...

Chapter 14 scoped样式以及data函数

欢迎大家订阅【Vue2Vue3】入门到实践 专栏&#xff0c;开启你的 Vue 学习之旅&#xff01; 文章目录 1 scoped样式1.1 全局样式1.2 局部样式1.3 工作原理2 data函数 1 scoped样式 1.1 全局样式 全局样式是指作用于整个应用程序的样式&#xff0c;不论在哪个组件中定义&#x…...

Golang | Leetcode Golang题解之第557题反转字符串中的单词III

题目&#xff1a; 题解&#xff1a; func reverseWords(s string) string {length : len(s)ret : []byte{}for i : 0; i < length; {start : ifor i < length && s[i] ! {i}for p : start; p < i; p {ret append(ret, s[start i - 1 - p])}for i < le…...

区块链技术在电子政务中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 区块链技术在电子政务中的应用 区块链技术在电子政务中的应用 区块链技术在电子政务中的应用 引言 区块链技术概述 定义与原理 发…...

Simulink中Matlab function使用全局变量

目录 一. 引言二. 普通Matlab function使用全局变量三. Simulink中的Matlab function使用全局变量四. 如何利用Matlab function的全局变量施加随机噪声 一. 引言 最近发现了之前仿真中的一个问题&#xff0c;记录一下备忘。 Matlab function中有时候需要用到全局变量&#xf…...

WPF-控件的属性值的类型转化

控件的属性值需要转成int、double进行运算的&#xff0c;可以使用一下方法 页面代码 <StackPanel Margin"4,0,0,0" Style"{StaticResource Form-StackPanel}"> <Label Content"替换后材料增加金额&#xff…...

海思Hi3516DV300上播放G711U音频文件

在海思Hi3516DV300芯片运行Linux系统下&#xff0c;可通过如下函数来实现G711U音频文件的播放&#xff1a; int ADecPlayVoiceFile(const char* filename) {FILE* pfd;AUDIO_STREAM_S stStream;HI_S32 s32Ret,length,decLength,allLength 0,aChn 0;HI_U8 buf[SAMPLE_AUDIO_P…...

Linux源码阅读笔记-V4L2框架基础介绍

V4L2视频设备驱动基础 V4L2 是专门为 Linux 设备设计的整套视频框架&#xff08;其主要核心在 Linux 内核&#xff0c;相当于 Linux 操作系统上层的视频源捕获驱动框架&#xff09;。为上层访问系统底层的视频设备提供一个统一的标准接口。V4L2 驱动框架能够支持多种类型设备&…...

列表(list)

一、前言 本次博客主要讲解 list 容器的基本操作、常用接口做一个系统的整理&#xff0c;结合具体案例熟悉自定义内部排序方法的使用。如有任何错误&#xff0c;欢迎在评论区指出&#xff0c;我会积极改正。 二、什么是list list是C的一个序列容器&#xff0c;插入和删除元素…...

使用Python抓取数据的实战指南

引言 在当今信息爆炸的时代&#xff0c;数据已成为一种宝贵的资源。无论是学术研究、市场分析&#xff0c;还是个人兴趣&#xff0c;数据的获取都是至关重要的一步。Python&#xff0c;凭借其强大的库和简洁的语法&#xff0c;成为了数据抓取&#xff08;也称为网络爬虫或网页…...

GIC寄存器介绍

往期内容 本专栏往期内容&#xff0c;interrtupr子系统&#xff1a; 深入解析Linux内核中断管理&#xff1a;从IRQ描述符到irq domain的设计与实现Linux内核中IRQ Domain的结构、操作及映射机制详解中断描述符irq_desc成员详解Linux 内核中断描述符 (irq_desc) 的初始化与动态分…...

c++实现B树(下)

书接上回小吉讲的是B树的搭建和新增方法的实现&#xff08;blog传送门&#x1f6aa;&#xff1a;B树实现上&#xff09;&#xff08;如果有小可爱对B树还不是很了解的话&#xff0c;可以先看完上一篇blog&#xff0c;再来看小吉的这篇blog&#xff09;。那这一篇主要讲的是B树中…...

外星人入侵

学习于Python编程从入门到实践&#xff08;Eric Matthes 著&#xff09; 整体目录&#xff1a;外星人入侵文件夹是打包后的不必在意 图片和音效都是网上下载的 音效下载网站&#xff1a;Free 游戏爆击中 Sound Effects Download - Pixabay 运行效果&#xff1a;可以上下左右移…...