「Java 路线」| 编译过程(编译前端 & 编译后端)

简介: 「Java 路线」| 编译过程(编译前端 & 编译后端)

前言


  • 经过前面几篇文章的积累,相信你已经掌握了 静态的 Class 文件的结构,也理解了虚拟机类加载和字节码执行的 动态过程
  • 这篇文章,我们来聊一聊 Java 的编译过程,你将看到从源码到字节码再到本地代码的整个过程。请点赞,你的点赞和关注真的对我非常重要!


目录

image.png


1. 经典程序编译原理


将源代码翻译为目标代码的过程,称为编译过程,经典的程序编译过程包含以下过程:


image.png

  • 如果将目标代码理解为中间代码,就是狭义上的编译过程。例如*.c文件编译生成*.obj文件的过程,或者*.java文件编译生成*.class文件的过程;
  • 如果将目标代码理解为最终执行的机器代码,那就是广义上的编译过程。那么还包括*.obj文件链接为可执行的*.exe文件的过程,或者*.class解释 / 编译为机器代码的过程;


image.png

Java技术下,除非有特定的上下文语境,编译一词通常指的是*.java转换为*.class的过程,这个过程也被称为 编译前端。除此之外,编译一词还可以指运行期即时编译(JIT,Just in Time Compile)或者(静态的)提前编译(AOT,Ahead of Time Compile),这两种编译称为 编译后端


下面,我们整理一下 编译前端 & 编译后端 的要点:


2. 编译前端


编译前端阶段中,最重要的一个编译器就是javac 编译器, 在命令行执行javac命令,其实本质是运行了javac.exe这个应用。Android工程师可能对于 Gradle构建过程更为熟悉,构建过程中有一个Task:compileDebugJavaWithJavac,其实也用到了javac 编译器,编译中间产物路径在build/intermediates/javac/debug/classes


2.1 javac 编译


下面,我们整理javac 编译器的主要处理过程:

image.png


延伸文章:



2.2 Java 常用语法糖


语法糖 指的是高级语言中的某种语法,这些语法糖在编译时进行解语法糖,转换为无糖语法。这些语法糖大多都是靠编译器实现,而不是依赖字节码或者虚拟机的底层支持。下表总结了部分熟知的语法糖:

image.png


延伸文章:



3. 编译后端


在编译后端阶段中,最重要的是 运行期即时编译器(JIT,Just in Time Compiler)和 静态的提前编译器(AOT,Ahead of Time Compiler)。


3.1 解释执行 & 编译执行


根据前面的内容,我们知道编译前端的核心编译产物是:Class 文件。但是对于CPU来说,它是不认得字节码的。在《Java | 为什么 Java 实现了平台无关性》这篇文章里,我们强调了:每种CPU只能“读懂”自身支持的机器语言或者本地代码(native code)

因此,Java 虚拟机在执行字节码时,需要将字节码翻译为当前平台的本地代码,可以分为:解释执行 & 编译执行,具体如下:


image.png

需要注意的是,并不是所有的Java 虚拟机都采用解释器与编译器并存的运行架构。当触发即时编译时,执行引擎(默认)不会等待即时编译完成,而是先按解释执行的方式继续执行。直到即时编译完成后,方法的入口地址才会被修改。


3.2 即时编译器热点探测


那么,即时编译器是如何探测热点代码的呢?具体来说,探测的热点代码有两种::被多次调用的方法 & 被多次执行的循环体。使用的探测方法有:基于采样 & 基于计数器


image.png

3.3 编译器优化技术


Editting...


4. 总结


  • 编译前端的优化措施主要目的是降低程序员的编码复杂度,提高编码效率。语法糖并不是不是依赖字节码或者虚拟机的底层支持,在编译后会转换为基础的无糖语法。另外,注解处理器相当于编译器的插件,开发人员可以通过它对前端编译施加影响。
  • 编译后端的优化措施主要目的是生成更高效的机器代码,提高运行效率。提前编译在程序运行前编译字节码,相当于提前预热。而即时编译器在运行时动态监控程序运行,探测得热点代码后编译为本地代码,生成的代码更高效,但需要预热期。
目录
相关文章
|
4天前
|
前端开发 JavaScript API
解锁高效应用构建:Vuex与后端交互的前端状态同步策略,让数据流动如行云流水,紧跟前端开发的热点趋势
【8月更文挑战第27天】本文深入探讨了Vue框架下的前端状态管理库Vuex与后端服务交互时的状态同步策略。通过剖析Vuex的核心机制——状态(State)、变异(Mutation)、动作(Action)及模块(Module),文章展示了如何优雅地将后端数据加载并更新至前端状态中。特别地,借助示例代码解释了Action处理API调用、Mutation更新状态的过程,并介绍了如何通过模块化和命名空间提高状态管理的准确性和时效性。此外,还讨论了组件如何利用`mapState`和`mapActions`简化状态访问与操作的方法。遵循这些策略,开发者可以在构建复杂应用时显著提升性能与用户体验。
17 0
|
15天前
|
设计模式 前端开发 Java
【前端学java】SpringBootWeb极速入门-分层解耦(03)
【8月更文挑战第13天】SpringBootWeb极速入门-分层解耦(03)
12 2
【前端学java】SpringBootWeb极速入门-分层解耦(03)
|
16天前
|
开发框架 前端开发 Java
【前端学java】SpringBootWeb极速入门-实现一个简单的web页面01
【8月更文挑战第12天】SpringBootWeb极速入门-实现一个简单的web页面01
35 3
【前端学java】SpringBootWeb极速入门-实现一个简单的web页面01
|
16天前
|
前端开发 Java Maven
【前端学java】全网最详细的maven安装与IDEA集成教程!
【8月更文挑战第12天】全网最详细的maven安装与IDEA集成教程!
37 2
【前端学java】全网最详细的maven安装与IDEA集成教程!
|
16天前
|
JSON 前端开发 Java
【前端学java】SpringBootWeb极速入门-请求参数解析(02)
【8月更文挑战第12天】SpringBootWeb极速入门-请求参数解析(02)
12 1
【前端学java】SpringBootWeb极速入门-请求参数解析(02)
|
1天前
|
存储 安全 Java
深入探讨Java的分层编译
本文主要探讨Java虚拟机(JVM)中的分层编译(Tiered Compilation)机制及其对程序性能的影响。
|
10天前
|
前端开发 Java 数据库
Java系列之 Long类型返回前端精度丢失
这篇文章讨论了Java后端实体类中Long类型数据在传递给前端时出现的精度丢失问题,并提供了通过在实体类字段上添加`@JsonSerialize(using = ToStringSerializer.class)`注解来确保精度的解决方法。
|
13天前
|
前端开发 IDE Java
"揭秘前端转Java的秘径:SpringBoot Web极速入门,掌握分层解耦艺术,让你的后端代码飞起来,你敢来挑战吗?"
【8月更文挑战第19天】面向前端开发者介绍Spring Boot后端开发,通过简化Spring应用搭建,快速实现Web应用。本文以创建“Hello World”应用为例,展示项目基本结构与运行方式。进而深入探讨三层架构(Controller、Service、DAO)下的分层解耦概念,通过员工信息管理示例,演示各层如何协作及依赖注入的使用,以此提升代码灵活性与可维护性。
28 2
|
13天前
|
缓存 前端开发 JavaScript
高效开发现代 Web 应用:从前端到后端的最佳实践
在开发现代 Web 应用时,前端和后端技术的选择对项目的性能、可维护性和用户体验至关重要。本文将探讨如何通过现代工具和框架来优化前端和后端开发流程。我们将分析前端技术(如 React 和 Vue.js)与后端技术(如 Node.js 和 Django)的集成,并提供实际案例来展示如何实现高效开发。无论是对新手还是经验丰富的开发者,本指南都提供了宝贵的洞见和实用的技巧,以帮助提高开发效率并构建出色的 Web 应用。
|
16天前
|
前端开发 JavaScript Java
java实现异步回调返回给前端
综上,Java中实现异步回调并将结果返回给前端是一项涉及后端异步处理和前端交互的综合任务。在实际项目中,开发人员需要根据应用需求和性能预期选择合适的异步模型与工具,并进行适当的配置和优化。
50 3
下一篇
云函数