ARTS - Share 补11.26

一个.java 文本文件是如何运行起来的

整体

我们知道,通常的说法是 .java被编译器编译成.class文件,也就是字节码文件,然后虚拟机加载执行。这是粗略的说法,具体实现是有些复杂的,如

  1. 编译器如何把.java 文件编译成.class字节码文件的?
  2. 虚拟机是如何加载编译后的字节码文件的?
  3. 为什么要用虚拟机来执行Java程序?

1.编译Java

Java编译使用javac命令,编译器输入java源码文件, 输出机器语言,具体过程如下:

java源代码(符合语言规范)-> javac -> .class字节码文件 -> jvm -> 机器语言(不同平台不同种类)

编译流程:

  • 词法分析器:将源码转换为Token流
    • 将源代码划分成一个个Token(找出java语言中的if,else,for等关键字)
  • 语法分析器:将Token流转化为语法树
    • 将上述的一个个Token组成一句句话(或者说成一句句代码块),检查这一句句话是不是符合Java语言规范(如if后面跟的是不是布尔判断表达式)
  • 语义分析器:将语法树转化为注解语法树
    • 将复杂的语法转化成简单的语法(eg.注解、foreach转化为for循环、去掉永不会用到的代码块)并做一些检查,添加一些代码(默认构造器)
  • 代码生成器:将注解语法树转化为字节码(即将一个数据结构转化成另一个数据结构)

2.虚拟机加载

完成构造字节码文件后,虚拟机加载.class文件

3.为什么要用虚拟机

跨平台

因为不同的操作系统接口不同。

我们知道操作系统就是管理计算机硬件,提供操作接口。比如删除硬盘文件的接口,在window上可能叫deleteFile, 在linux可能叫removeFile, 那么我们写程序,不会去判断运行的操作系统,可能就是一句delete, 那么虚拟机就会根据不同的操作系统去选择对应的操作接口。

这样,就等于我们编写一次,导出执行。也就是虚拟机的跨平台自适应,让我们的程序也跟着实现了跨平台。

自动内存管理

虚拟机帮我们实现了内存管理。我们避免了申请、释放内存这个步骤,统一由虚拟机自行管理,这样我们只要专注于逻辑实现就行了,降低了代码难度,降低了低水平程序员的错误概率。

优化代码执行

执行最快的是机器语言,也就是0,1操作,然后就是汇编,之后就是各种语言。虚拟机会分析代码执行的频繁度,把高密度使用的代码翻译成机器语言,提高效率。