11.4java语言执行浅析4

news2025/6/3 8:45:51

编译成字节码(.class 文件)

使用 javac 命令将源代码编译为 Java 字节码(bytecode) 

它不是机器码,而是 JVM 能理解的中间语言(字节码),具有平台无关性。

编译过程简要:

  1. 词法分析:将字符序列转换为标记(token)。
  2. 语法分析:构建抽象语法树(AST)。
  3. 语义分析:检查类型、变量是否合法。
  4. 生成字节码:将 AST 转换为 .class 文件中的字节码指令。

类加载(Class Loading)

当你运行程序时,JVM 启动并开始加载所需的类:

JVM 使用 类加载器(ClassLoader) 来加载 .class 文件。类加载包括以下步骤:

  • 加载(Loading):查找并导入类的 .class 文件。
  • 验证(Verification):确保字节码是安全且符合规范的。
  • 准备(Preparation):为类变量分配内存,并设置默认初始值。
  • 解析(Resolution)(可选延迟):将符号引用替换为直接引用。
  • 初始化(Initialization):执行类构造器 <clinit> 方法(静态变量赋值和静态代码块)。

执行字节码(Execution Engine)

Java 字节码由 JVM 的执行引擎来执行。具体方式有三种:

1. 解释执行(Interpretation)

JVM 逐条解释字节码并执行,速度较慢但跨平台兼容性强。

2. 即时编译(JIT Compilation)

热点代码(频繁执行的代码)会被 JIT 编译器动态编译为本地机器码,提升性能。

3. 本地方法调用(Native Method)

某些操作(如 I/O、线程)通过调用操作系统原生库实现。


垃圾回收(Garbage Collection)

在程序运行期间,JVM 自动管理内存,GC 会定期回收不再使用的对象,释放内存资源。


程序终止

main() 方法执行完毕,或者遇到异常、系统退出等,JVM 关闭,程序结束。


总结流程图

Java源代码 (.java)
      ↓ 编译 (javac)
字节码文件 (.class)
      ↓ 运行 (java)
类加载 → 验证 → 准备 → 解析 → 初始化
      ↓
执行引擎(解释 + JIT 编译)
      ↓
垃圾回收 & 程序终止

.class 文件整体结构(以字节为单位)

类型数量描述
魔数(magic)u41固定值 0xCAFEBABE,标识这是 Java class 文件
次版本号(minor_version)u21次版本号
主版本号(major_version)u21主版本号,如 52 表示 JDK 8
常量池计数器(constant_pool_count)u21常量池项数量(从 1 开始编号)
常量池(constant_pool)cp_info[]constant_pool_count - 1存储各种常量(字符串、类名、字段名等)
访问标志(access_flags)u21类的访问权限(public、abstract 等)
类索引(this_class)u21当前类的常量池索引
超类索引(super_class)u21父类的常量池索引
接口计数器(interfaces_count)u21实现的接口数量
接口表(interfaces)u2[]interfaces_count接口的常量池索引数组
字段计数器(fields_count)u21字段数量
字段表(fields)field_info[]fields_count字段的详细信息
方法计数器(methods_count)u21方法数量
方法表(methods)method_info[]methods_count方法的详细信息
属性计数器(attributes_count)u21属性数量
属性表(attributes)attribute_info[]attributes_count属性信息(如 SourceFile、Code 等)

各部分详解

1. 魔数(Magic Number)

  • 固定值:0xCAFEBABE
  • 用于识别是否是合法的 class 文件。

2. 版本号(Version)

  • minor_version + major_version
  • 常见主版本号对应:
    • JDK 1.1: 45
    • JDK 1.2: 46
    • ...
    • JDK 8: 52
    • JDK 17: 61

3. 常量池(Constant Pool)

  • 是 .class 文件中最复杂也最重要的结构之一。
  • 包含多种类型的常量,例如:
    • 类名、字段名、方法名
    • 字符串常量
    • 方法引用、字段引用
    • UTF-8 字符串等

常量池中的每一项都有一个 tag 字段表示类型,比如:

  • CONSTANT_Utf8 (1)
  • CONSTANT_Class (7)
  • CONSTANT_Fieldref (9)
  • CONSTANT_Methodref (10)
  • ...

4. 访问标志(Access Flags)

  • 标识该类是 public、final、interface、abstract 等。

5. 类索引、超类索引、接口表

  • 通过常量池索引来引用当前类、父类和实现的接口。

6. 字段表(Fields)

  • 描述类中声明的变量(包括静态变量、实例变量等)。
  • 每个字段包含:
    • 名称索引
    • 描述符索引(描述字段类型)
    • 属性表(如 ConstantValue、Synthetic 等)

7. 方法表(Methods)

  • 描述类中声明的方法。
  • 每个方法包含:
    • 名称索引
    • 描述符索引(参数和返回值类型)
    • 属性表(如 Code、Exceptions、LineNumberTable 等)

方法体(Code 属性)

  • 在方法的属性表中,Code 属性是最核心的部分,它包含:
    • 操作数栈最大深度
    • 局部变量表大小
    • 字节码指令(bytecodes)
    • 异常处理表
    • 其他调试信息(如行号表)

8. 属性表(Attributes)

  • 用于扩展 class 文件的附加信息。
  • 常见属性有:
    • Code:方法的字节码
    • SourceFile:记录源文件名
    • LineNumberTable:源码与字节码的行号映射
    • LocalVariableTable:局部变量表信息
    • Exceptions:方法抛出的异常列表
    • BootstrapMethods:用于动态语言支持(如 Lambda 表达式)

示例解析(简单 Hello.class)

假设我们有如下 Java 源码:

public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}

编译后生成的 Hello.class 文件结构大致如下:

magic:              CAFE BABE
minor_version:      0
major_version:      52 (JDK 8)
constant_pool:      [各种符号引用]
access_flags:       0x0031 (public final super)
this_class:         #5 => "Hello"
super_class:        #6 => "java/lang/Object"
interfaces:         none
fields:             none
methods:
  - main: descriptor ([Ljava/lang/String;)V, flags: public static
    attributes:
      - Code:
          max_stack: 2
          max_locals: 1
          code_length: 10
          code:
            0: getstatic     #2  // Field java/lang/System.out:Ljava/io/PrintStream;
            3: ldc           #3  // String Hello World
            5: invokevirtual #4  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            8: return
          exception_table: empty
          attributes: LineNumberTable, LocalVariableTable

 查看 .class 文件内容的工具

你可以使用以下工具来查看 .class 文件的内容:

1. javap 反汇编工具(JDK 自带)

javap -c -verbose Hello.class
  • -c:显示字节码指令
  • -verbose:显示更详细的结构信息(包括常量池、属性等)

2. 二进制编辑器(如 Hex Editor)

  • 可查看原始的十六进制数据。
  • 如:WinHex、HxD、xxd 等。

3. ASM、ByteBuddy、Javassist 等字节码操作库

  • 可用于分析、修改 .class 文件内容,常用于 AOP、性能监控、热修复等高级场景。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python分配方案数 2023年信息素养大赛复赛/决赛真题 小学组/初中组 python编程挑战赛 真题详细解析

python分配方案数 2023全国青少年信息素养大赛Python编程挑战赛复赛真题解析 博主推荐 所有考级比赛学习相关资料合集【推荐收藏】1、Python比赛 信息素养大赛Python编程挑战赛 蓝桥杯python选拔赛真题详解

《信号与系统》第 5 章 离散时间傅里叶变换

5.0 引言 这一章将介绍并研究离散时间傅里叶变换&#xff0c;这样就完整地建立了傅里叶分析方法。 5.1 非周期信号的表示&#xff1a;离散时间傅里叶变换 5.1.1 离散时间傅里叶变换的导出 在第4章看到&#xff1a;一个连续时间周期方波的傅里叶级数可以看成一个包络函数的采…

动态IP与区块链:重构网络信任的底层革命

在数字经济蓬勃发展的今天&#xff0c;网络安全与数据隐私正面临前所未有的挑战。动态IP技术与区块链的深度融合&#xff0c;正在构建一个去中心化、高可信的网络基础设施&#xff0c;为Web3.0时代的到来奠定基础。 一、技术碰撞&#xff1a;动态IP与区块链的天然契合 动态I…

uniapp使用Canvas生成电子名片

uniapp使用Canvas生成电子名片 工作中有生成电子名片的一个需求&#xff0c;刚刚好弄了发一下分享分享 文章目录 uniapp使用Canvas生成电子名片前言一、上代码&#xff1f;总结 前言 先看效果 一、上代码&#xff1f; 不对不对应该是上才艺&#xff0c;哈哈哈 <template…

世冠科技亮相中汽中心科技周MBDE会议,共探汽车研发数字化转型新路径

近日&#xff0c;中汽中心2025年科技周MBDE前沿应用主题会议在天津成功举办。本次会议以“智汇津门共探MBDE前沿应用新征程”为主题&#xff0c;聚焦基于模型的数字工程&#xff08;MBDE&#xff09;方法论在汽车复杂系统研发中的创新实践与跨领域协同&#xff0c;旨在推动行业…

Linux笔记---线程

1. 线程的介绍 1.1 线程的概念 基本定义&#xff1a; 线程&#xff08;Thread&#xff09;是操作系统能够进行运算调度的最小单位。它被包含在进程&#xff08;Process&#xff09;之中&#xff08;或者说是进程的一部分、对进程的划分&#xff09;&#xff0c;是进程中的实际…

MCP架构深度解析:从基础原理到核心设计

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 持续学习&#xff0c;不断…

数据库暴露--Get型注入攻击

1.背景知识 1.1Post、Get的对比 特性GET 方法POST 方法HTTP 方法类型GETPOST数据位置URL 查询字符串(?key=value)请求体(Request Body)数据可见性明文显示在 URL 和浏览器历史中不可见(除非开发者工具查看)数据长度限制受 URL 长度限制(通常约 2048 字符)无明确限制(…

AI炼丹日志-26 - crawl4ai 专为 AI 打造的爬虫爬取库 上手指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇&#xff1a; MyBatis 更新完毕目前开始更新 Spring&#xff0c;一起深入浅出&#xff01; 大数据篇 300&#xff1a; Hadoop&…

ESP32-idf学习(四)esp32C3驱动lcd

一、前言 屏幕是人机交互的重要媒介&#xff0c;而且现在我们产品升级的趋势越来越高大尚&#xff0c;不少产品都会用lcd来做界面&#xff0c;而esp32c3在一些项目上是可以替代主mcu&#xff0c;所以驱动lcd也是必须学会的啦 我新买的这块st7789&#xff0c;突然发现是带触摸…

【python】uv管理器

uv是一个速度极快的 Python 包和项目管理器&#xff0c;用 Rust 编写。 安装 安装uv之前&#xff0c;确保你的电脑不需要安装了python 在Windows下&#xff0c;可以使用官方的脚本直接安装 powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.…

戴尔AI服务器订单激增至121亿美元,但传统业务承压

戴尔科技121亿美元的AI服务器订单&#xff0c;不仅超过了公司整个2025财年的AI服务器出货量&#xff0c;更让其AI订单积压达到144亿美元的历史高位。 戴尔科技最新财报显示&#xff0c;AI服务器需求的爆炸式增长正在重塑这家老牌PC制造商的业务格局&#xff0c;但同时也暴露出…

如何手搓扫雷(待扩展)

文章目录 一、扫雷游戏分析与设计1.1 扫雷游戏的功能说明1.2 游戏的分析和设计1.2.1 数据结构的分析1.2.2 文件结构设计 二、扫雷游戏的代码实现三、扫雷游戏的扩展总结 一、扫雷游戏分析与设计 扫雷游戏网页版 1.1 扫雷游戏的功能说明 使用控制台&#xff08;黑框框的程序&a…

俄军操作系统 Astra Linux 安装教程

安装 U盘制作 Rufus 写盘工具&#xff1a;https://rufus.ie/ Astra Linux ISO 镜像文件&#xff1a;https://dl.astralinux.ru/astra/stable/2.12_x86-64/iso/ 准备一个8g以上的u盘&#xff0c;打开Rufus写盘工具&#xff0c;选择下载的iso镜像&#xff0c;写入u盘&#xff…

第三方软件评测机构如何助力软件品质提升及企业发展?

第三方软件评测机构与软件开发者及使用者无直接关联&#xff0c;它们提供全方位的检测和公正的评价服务。这样的评测可以展现客观的成效&#xff0c;对提升软件的品质具有显著影响&#xff0c;且在软件产业中发挥着至关重要的角色。 评测的客观性 独立第三方机构与软件开发者…

Python打卡训练营Day40

DAY 40 训练和测试的规范写法 知识点回顾&#xff1a; 彩色和灰度图片测试和训练的规范写法&#xff1a;封装在函数中展平操作&#xff1a;除第一个维度batchsize外全部展平dropout操作&#xff1a;训练阶段随机丢弃神经元&#xff0c;测试阶段eval模式关闭dropout 作业&#x…

JS逆向案例—喜马拉雅xm-sign详情页爬取

JS逆向案例——喜马拉雅xm-sign详情页爬取 声明网站流程分析总结 声明 本文章中所有内容仅供学习交流&#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&am…

STM32CubeMX定时器配置

STM32CubeMX定时器配置 一&#xff0c;Mode界面1&#xff0c;Slave Mode (从模式)2&#xff0c;Trigger Source (触发源) 三&#xff0c;Channelx&#xff08;通道模式&#xff09;1&#xff0c;Input Capture2&#xff0c;Output Compare3&#xff0c;PWM Generation4&#xf…

QNAP MEMOS 域名访问 SSL(Lucky)

注意&#xff1a;下述是通过ssh、docker-compose方式安装docker的&#xff0c;不是直接在container station中安装的哈&#xff01;&#xff01;&#xff01; 一、编辑docker-compose.yml文件 用“#”号标识的&#xff0c;在保存文件的时候建议去掉&#xff0c;不然有时候会出…

如何将多张图组合到一张图里同时保留高的分辨率(用PPT+AdobeAcrobat)

文章目录 一、用PPT排版得到一页排布了很多图片的PPT二、用AdobeAcrobat打开pdf文件三、最后得到的图片 一、用PPT排版得到一页排布了很多图片的PPT 步骤如下 ①将幻灯片大小的长设置为17.2&#xff0c;宽根据图像多少进行调整&#xff0c;我这里是10 幻灯片大小的长设置步骤&…