javac编译过程

Javac编译源码为字节码的过程 对于上述代码片段,语法树可能包含一个变量声明节点,其中包含一个类型节点(“int”)和一个变量节点(“num”),还有一个赋值节点,其中包含一个变量节点和一个常量节点。在这个阶段,Javac将语法树转换为字节码表示形式,字节码是一系列操作码(Opcode)和操作数的序列。总结起来,Javac将源代码编译为字节码的过程包括词法分析、语法分析、语义分析、中间代码生成、优化和字节码生成。生成字节码(Bytecode Generation):最后,Javac将经过优化的中间代码转换为最终的字节码文件。 阅读详情

概览(一句话)

把 .java 源文件变成 .class 字节码文件的过程,主要包括:词法/语法分析 → 符号表建立 → 注解处理(可生成新源) → 类型检查与数据流分析 → 语法糖转换/泛型擦除 → 字节码生成 → 写出 class 文件(可再打包为 jar)。

详细编译阶段(按执行顺序)

下面按典型 javac(OpenJDK)内部流程把各阶段讲清楚:

  1. 源文件输入(.java)

    • 编译器从磁盘读取 .java 文件,按编码解析字符(可通过 -encoding 指定)。

  2. 词法分析(Lexical analysis / Tokenize)

    • 把字符流拆成 token(关键字、标识符、字面量、符号等)。

  3. 语法解析(Parsing) → 抽象语法树(AST)

    • 根据 Java 语法把 token 解析成 AST(编译单元、类/方法/表达式的树形结构)。

  4. Enter(符号表收集)

    • 收集声明(类、接口、字段、方法、包等),建立符号表(symbol table)。此阶段主要识别“名字在哪儿声明”。

  5. 注解处理(Annotation Processing)

    • 编译器调用注册的注解处理器(javax.annotation.processing)——比如 Lombok、编译期生成代码的处理器。

    • 注解处理可以生成新的源文件或其它资源,生成后会触发新的编译轮次(处理器可能被执行多轮直到没有新文件生成)。

    • 可通过 -processor、-proc:only 等控制。

  6. 类型属性与语义分析(Attribution / Type checking)

    • 名称解析(将变量/方法名绑定到符号表中的具体声明)、重载解析、类型推断、泛型边界检查等。

    • 检查方法签名、可访问性(public/private)、接口实现是否完整等。

  7. 数据流分析(Flow analysis)

    • 包括“definite assignment”(确定性赋值)检查、不可达代码检测、局部变量的初始化性检查等。

  8. 泛型擦除 & 桥方法(TransTypes)

    • Java 的泛型在编译时进行 类型擦除(type erasure):泛型信息不会保留在运行时(大多数场景)。

    • 编译器为保持运行时多态,可能生成 bridge methods(桥方法)(例如子类泛型导致方法签名不同,需要桥方法来保持父子兼容)。

  9. 语法糖转换 / 降低(Desugaring / Lowering)

    • 把高级语言结构转换为 JVM 能理解的形式,例如:

      • 内部类 / 匿名类 → 生成 Outer$Inner.class 或 Outer$1.class 等,并可能添加 synthetic 字段/方法以访问外部变量。

      • lambda 表达式(Java 8+) → 主要通过 invokedynamic+引导方法(bootstrap)实现(编译期生成 invokedynamic 指令与必要的“目标方法”引用;不一定每次都生成独立类)。

      • 枚举(enum) → 编译成类,静态 final 实例和 values()/valueOf() 方法等。

      • switch on String → 编译器将字符串转换为 hashCode() + equals 的处理逻辑或辅助表。

      • assert → 转换成条件判断语句(如果开启断言)。

  10. 字节码生成(Code generation)

    • 根据处理过的 AST 生成 JVM 字节码(方法的字节码、常量池、字段、属性等)。

    • 同时生成 class file 的各种 attributes(LineNumberTable、LocalVariableTable、SourceFile 等,取决于 -g 等选项)。

  11. 写出 .class 文件

    • 把生成的字节码与常量池、类文件头(magic number、版本号)等写入磁盘 .class 文件。

  12. 后处理 / 打包(可选)

    • 使用 jar 打包、使用字节码工具做混淆(ProGuard/Obfuscator)、AOT 编译或 native-image 等(这些属于构建或运行时工具链外的步骤)。

类文件(.class)结构(简要)

.class 文件主要包含:

  • magic(0xCAFEBABE)、minor/major version(类文件版本,与 Java 版本对应)

  • Constant Pool(常量池)(字符串、类名、方法引用、字面量等)

  • 访问标志(public/abstract/final)

  • this_class / super_class / interfaces

  • fields(字段表)

  • methods(方法表:包含字节码)

  • attributes(类级属性,比如 SourceFile,RuntimeVisibleAnnotations 等)

可以用 javap -v ClassName 查看这些信息(常用于排查编译后产生的字节码/常量池内容)。

一些关键细节(面试/排错常用点)

  • 泛型是编译时检查,运行时类型擦除:List<String> 与 List<Integer> 在字节码层面是相同的。

  • 桥方法:为保持泛型/协变重写的二义性/兼容性,编译器会自动生成桥方法。

  • lambda:不再总是生成匿名内部类,而是采用 invokedynamic(减少类数量、提高性能)。

  • 注解处理器:可以生成新源码或资源,务必注意生成的类的包名、类名不冲突,且可能需要多轮编译。

  • 内部类 & 匿名类:会产生额外的 .class 文件(带 $ 符号),注意在打包/反射时路径变化。

  • 调试信息:-g(默认一般会生成行号/本地变量等),-parameters 可把方法参数名保留到 class 文件(用于反射获得真实参数名)。

  • 跨版本编译:使用 --release(推荐)或 -source/-target 来控制生成的字节码兼容性;--release 还能为目标平台选择正确的核心库签名。

常见编译命令:

# 编译单个文件并指定输出目录
javac -d out -encoding UTF-8 src/com/example/Main.java

# 指定 classpath 并编译整个源码目录
javac -d out -classpath "lib/*" $(find src -name "*.java")

# 用 --release 指定目标 Java 版本(推荐用于跨版本编译)
javac --release 11 -d out src/com/example/*.java

# 仅运行注解处理器(不生成 class)
javac -proc:only -processor com.example.YourProcessor src/...

# 生成带参数名的 class(反射可见)
javac -parameters src/...

#打包
jar cvf app.jar -C out .


javap -c -p com.example.Main    # 查看反汇编字节码
javap -v com.example.Main       # 查看详细(含常量池)

基于STM32的HC-SR04超声波模块测距(新手级) 本人是嵌入式新手,学习了STM32的部分内容,最近想找些项目做,然后顺便学习了一下HC-SR04超声波模块,学习过程中也参考了一些大佬的文章。本文记录了自己的学习方法和学习过程,同时也希望能和各位大佬交流讨论。 阅读详情

相关推荐

树莓派与无人机协同实战:基于OpenCV的地标识别优化策略

本文深入探讨了基于树莓派与无人机的协同系统,重点分享了利用OpenCV优化地标识别以实现精准降落的实战策略。内容涵盖从应对复杂光照的图像预处理、鲁棒的轮廓几何过滤,到通过ROS进行稳定通信,以及实现分层控制与状态机设计,旨在提升系统在真实环境中的可靠性与性能。

y2z3a4b5c的博客 1085

Java基础 - javac命令详解(1) 编译基本java项目

1.为什么要搞定 javac 命令 1.javac 是java中的编译源代码的命令工具,将.java文件编译成 .class 文件; 2.由于当下为了提高开发效率,大多数的开发工作都在 java的 集成开发环境中进行,因此,也就很少有机会直接使用javac命令来编译我们的代码; 本文就对javac命令的使用场景进行一个较为系统的论述。 希望本文能够帮助到广大的 java coder! 2.javac 命令使用的两个场景 2.0 javac 语法介绍 1. javac 源文件 :

northcastle的博客 6万+

五子棋ai:极大极小搜索和α-β剪枝算法的思想和实现(qt和c++)(一)引言和界面设计

引言 alphaGo击败围棋冠军李世石的新闻让我对棋类博弈产生了浓厚的兴趣,无奈本人不会围棋,但算是一个五子棋业余爱好者,于是乎希望通过实现一个五子棋ai来了解相关算法和知识。 五子棋在英文中又称Gobang,five-in-row,还有两个称呼:gomoku和renju(连珠)。我来简要介绍一下区别。由于五子棋已经被机器严格证明了是一种**“不公平”的游戏,先手黑子是绝对占优的,并且先手有必胜*...

livingsu的博客 1万+

javac单独编译java文件

问题引入: 在工作当中因为部署好的代码有可能只有几行代码可以修改,这时候如果仍然在idea上面修改好后,打包再部署,那感觉太麻烦又费时间。因此想在线上服务器上面直接通过javac编译的方式编译单个文件即可。

3615

WeDetect:基于视觉-语言检索的目标检测新范式

目标检测正从传统回归与分类耦合范式,向开放、灵活、可扩展的多模态检索范式演进。检索式检测(Retrieval-based Detection)将检测任务重构为视觉特征与文本语义的联合匹配过程,依托候选框索引库与双塔架构,天然支持开放词汇、零样本识别与小目标定位。其技术价值在于解耦空间感知与语义理解,消除NMS与anchor匹配等冗余计算,显著提升推理效率与跨场景泛化能力。典型应用场景包括工业质检中的缺陷新增识别、遥感图像小目标检测、低光照鲁棒视觉系统等。WeDetect正是这一范式的代表性实现,深度融合视觉

weixin_30878501的博客 361

Xilinx-复旦微-FPGA-眼图BlockDesign系统制作-针对PCIE系统

XIlinx-复旦微电子-FPGA-眼图BlockDesign系统制作-针对PCIE系统,手把手教你如何建立眼图测试

weixin_43444334的博客 2596

Javac编译原理:基本结构和工作原理

Javac的编译原理,工作原理,基本结构

m0_73976305的博客 3797

告别连接难题:Windows 11下Multisim主数据库稳定运行终极配置指南

本文详细解析了Windows 11下Multisim 14.0主数据库连接失败的三大根源,并提供了四步终极解决方案,包括系统环境优化、软件权限配置、注册表修复和网络验证绕过技巧。通过实测数据对比,本方案显著提升了启动速度和稳定性,解决了电子仿真中的常见连接问题。

weixin_33738555的博客 432

Javac如何编译程序。

转化步骤     首先,要读取源代码,一个字节为一节的度进来,找出在这些字节中有哪些是我们定义的语法关键词,如Java中的if、else、for、while等关键词:要识别哪些if是合法的关联词,哪些不是,这个步骤就是词法分析过程。     此法分析的结果就是从源代码中找出一些规范化的Token流,就像在人类语言中,给你一句话,你要能分辨出其中哪些是词语,哪些是标点符号,哪些是动词,哪些是名词等...

孤芳不自赏 1330

YOLOv11 结合 BiFormer 注意力:打造多场景高精度检测模型实战教程

注册BiFormer模块(若代码未自动注册)# 加载自定义配置的YOLOv11模型。

know_F0727的博客 251

航空电子系统标准全景图:ARP4754A、ARP4761、DO-178C、DO-254 的协同作用

通过 ARP4754A、ARP4761、DO-178C 和 DO-254 的相互配合,确保航空电子系统的安全性和功能性在开发过程中得到充分保障。每一个文件在不同层面发挥作用,共同构成了一个完整的、系统的开发和验证框架,确保航空电子设备达到适航要求。这些标准不仅帮助开发人员有条理地开发复杂的航空系统,还确保所有系统组件(软件和硬件)在整个生命周期内都能满足最严格的安全和可靠性要求。

qq_41854911的博客 1812

Java之Javac编译

javac 是 Java 开发过程中不可或缺的一部分,它将 Java 源代码转换为可在 JVM 上运行的字节码。通过词法分析、语法分析、语义分析、字节码生成和优化等多个阶段,javac 确保了生成的代码既正确又高效。虽然 javac 的优化能力可能不如一些更高级的编译器,但它提供了足够的灵活性来适应大多数 Java 开发需求。随着 Java 语言的不断演进,javac 也将继续发展,以满足新的挑战和要求。

一个老Java开发的自白 1584

Hermes接入IMA知识库全攻略:将知识库装进你的Hermes智能体

本文详细介绍了如何将IMA知识库功能接入Hermes Agent平台,实现一站式笔记管理和知识库操作。主要内容包括:获取IMA访问凭证、下载技能包、配置凭据(支持文件和环境变量两种方式)、验证配置有效性,以及实际应用演示(查询知识库列表、创建笔记并添加到知识库)。文章还提供了常见问题解决方案,如认证失败处理、版本更新等。通过该集成,用户可在Hermes中直接调用IMA的笔记创建、知识库管理等强大功能,提升工作效率。

小石头的专栏 640

javac的编译过程

随风而逝的博客 2287

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

java编译过程_【JVM】javac的编译过程

Java 编译是先把xx.java文件编译成xx.class文件。xx.class是个中间状态的字节码(Byte Code)。类加载器(Class Loader)读取到JVM里后, 再一次解析成机器码(Binary Code)执行。也就是说Java是需要做两次编译,其中的第一次编译(.java => .class)是如何执行的呢?之前介绍过C语言编译执行是需要4个步骤(预处理,编译,汇编,链...

weixin_35962107的博客 1291

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Javac编译过程

Javac编译器将*.java文件编译成为*.class文件的过程,这里的Javac编译器称为前端编译器;相对应的还有后端编译器,它在程序运行期间将字节码转变成机器码。

lxy的学习笔记 6515

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Java系列——javac 的编译过程

javac 的编译过程

qq_41817756的博客 397

Javac编译过程笔记

Javac前端编译简述这里不讨论JIT编译、AOT编译,本文提到的编译过程仅仅指把.java文件转变为.class文件的过程,这个过程是我们最常见的,通常由Javac编译器来完成。Javac编译器对代码的运行效率几乎没做什么优化,虚拟机设计者把对代码性能的优化集中到了后端的JIT编译器中。之所以这样设计,因为Class文件拥有虚拟机规范严格定义的通用格式,只要符合Class文件格式,就可以被虚拟机正

Battling against our own ignorance 1012

Javac的编译过程

javac的编译过程: 解析和填充符号表->注解处理->语义分析和字节码生成 其中,注解处理之后,如果注解处理插件对语法树进行了修改,那么再回到解析和填充符号表步骤,重新开始这个Round,直到注解处理器不再对语法树进行修改为止。 这里说的不太细致。原因是,书上描述的也不太细致=。=,等我细致的了解过之后再来更新。

imzoer的专栏 1461

javac 编译过程

javac 编译过程 一、解析与填充符号表:   1. 语法、此法分析:   a) 语法分析:将源代码字符流转换为标记(Token:编译过程最小元素)集合。   b) 词法分析:根据标记序列构造抽象语法树(AST:用来描述程序代码语法结构的树形表示方式,每一个节点代表程序中的一个语法结构。   2. 填充符号表:一组符号地址和符号信息组成的...

weixin_30734435的博客 179

javac编译器的过程

javac编译器的过程: 1)解析与填充符号表过程     1,词法、语法分析     2,填充符号表 2)插入式注解处理器的注解处理过程 3)语义分析与字节码生成过程

xuqiaobo的博客 390

javac编译器的工作过程

前言: 当你跑起你写好的程序时,你是否好奇你的代码是怎么从一个.java的文件变成.class文件,又是怎么加载到jvm中的,又是怎么运行起来的吗?不知道不要紧今天就带你去了解一下; 先来介绍两个东西:javac(编译器)、jvm(虚拟机) javac: javac的任务是将Java源代码语言 (.java文件) 先转化成JVM能够识别的一种语言,然后由JVM将JVM语言再转化成当前这个机器能够识别的机器语言,javac的作用简单来说就是通过一些列的流程之后将.java文件转换为.class文件, ja

一只程序员的博客 582
上一篇: maven插件图标不见了?
下一篇: maven配置后,Tomcat老是找不到jar包,要手动配置
fqq3
博客等级 码龄4年 114粉丝 45原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值