JVM 真香系列:轻松理解 class 文件到虚拟机(上)
关注“Java 后端技术全栈”
回复“000”获取大量电子书
认识 JVM
![](https://static001.geekbang.org/infoq/4e/4e8555736829e89812d2629a201c1b5b.png)
什么是 JVM
JVM
全称 Java Virtual Machine,也就是我们耳熟能详的 Java 虚拟机。它能识别 .class 后缀的文件,并且能够解析它的指令,最终调用操作系统上的函数,完成我们想要的操作。
可能有部分小伙伴学习过 C++,C++开发出来的程序,编译成二进制文件后,就可以直接执行了,操作系统是能够识别的。
但是咱们开的的 Java 程序就不一样了,使用javac
命令编译出来的的.class 文件之后,操作系统是不能识别的,需要对应JVM
去做一个转换后,操作系统才能识别。
我们为什么不能像 C++ 一样,直接在操作系统上运行编译后的二进制文件呢?而非要搞一个处于程序与操作系统中间层的虚拟机呢?
这就是 JVM
的过人之处了。大家都知道,Java 是一门抽象程度特别高的语言,提供了自动内存管理等一系列的特性。这些特性直接在操作系统上实现是不太可能的,所以就需要JVM
进行做一系列的转换。
大家一开始学 Java 的时候,就知道有个 Write Once, Run Everywhere。就是我们编写了一个 java 文件经过编译成.class 文件后,可以在各种系统中进行运行。
其实这里是有个前提的,我们需要在对应操作系统中安装对应的JVM
,然后我们的.class 文件就能运行了。
比如:Windows 操作系统有对应的JDK
安装版本、Linux 也有对应的JDK
安装版本等。
![](https://static001.geekbang.org/infoq/b4/b47abb0a8e10a79ef237f070c3d58239.png)
认识 JDK
Java Development Kit (JDK
) 是 Sun 公司(已被 Oracle 收购)针对 Java 开发员的软件开发工具包。自从 Java 推出以来,JDK
已经成为使用最广泛的 Java SDK
(Software development kit)。
经非官方调查,目前JDK8
是使用者最多的版本。
JDK14
将在 4 月和 7 月收到安全更新,然后由 9 月到期的非 LTS 版本的JDK 15
取代。JDK14
包括 16 项新功能,例如JDK Flight Recorder
事件流,模式匹配和开关表达式等特征。
从JDK9
之后,Oracle 采用了新的发布周期:每 6 个月发布一个版本,每 3 年发布一个LTS
版本。JDK14
是继JDK9
之后发布的第四个版本, 该版本为非LTS
版本,最新的LTS
版本为JDK11
。
下面是JDK
版本情况
这个混个眼熟就行,随时关注JDK
版本更新和新特性。
官网地址:https://www.oracle.com/java/
关于JDK
安装这里就省略。
JDK、JRE、JVM 的关系
上面已经说过JDK
和JVM
的相关概念,
JRE
全程 Java Runtime Environment,是运行基于 Java 语言编写的程序所不可缺少的运行环境。也是通过它,Java 的开发者才得以将自己开发的程序发布到用户手中,让用户使用。
三者到底是什么关系呢?
关于三者关系请看官网
https://docs.oracle.com/javas...
JDK
中包含JRE
,也包括JDK
,而JRE
也包括JDK
。范围关系:JDK
>JRE
>JVM
".java"文件到".class"文件
javac
命令
编写一个HelloWorld.java
文件
内容就是一个Java
入门
打开CMD
,进入当前目录,使用命令
就编译出HelloWorld.class
![](https://static001.geekbang.org/infoq/99/996fc2ba3e2bddac13b27059ed3f28bb.png)
编译过程
这个 javac 命令过程到底干了些什么呢?
javac
背后大致做了这些操作
![](https://static001.geekbang.org/infoq/b1/b137a6688841896bc77eeb6241d9c0c0.png)
这个流程
![](https://static001.geekbang.org/infoq/47/477d9e95d76b5bb76d5c9b9926786867.png)
1、词法分析
读取源代码,一个字节一个字节的读取,找出其中我们定义好的关键字(如Java
中的 if、else、for、while 等关键词,识别哪些 if 是合法的关键词,哪些不是),这就是词法分析器进行词法分析的过程,其结果是从源代码中找出规范化的 Token 流。
2、语法分析
通过语法分析器对词法分析后 Token 流进行语法分析,这一步检查这些关键字组合再一次是否符合Java
语言规范(如在 if 后面是不是紧跟着一个布尔判断表达式),词法分析的结果是形成一个符合Java
语言规范的抽象语法树。
3、语义分析
通过语义分析器进行语义分析。语音分析主要是将一些难懂的、复杂的语法转化成更加简单的语法,结果形成最简单的语法(如将foreach
转换成 for 循环 ,好有注解等),最后形成一个注解过后的抽象语法树,这个语法树更为接近目标语言的语法规则。
4、生成字节码
通过字节码生产器生成字节码,根据经过注解的语法抽象树生成字节码,也就是将一个数据结构转化为另一个数据结构。最后生成我们想要的.class 文件。
使用十六进制查看 class 文件内容
我只用的是 Notepad++,选中文本→插件→Converter→ASCII->HEX
class 文件的开头就是
CAFEBABE
想要学习这里的十六进制的字节码的含义可以参考
https://docs.oracle.com/javas...
-
javap 查看 class 文件内容
javap
是 Java class 文件分解器,可以反编译(即对javac
编译的文件进行反编译),也可以查看java
编译器生成的字节码。
新建一个User.java
源文件,经过javac
编译后,生成User.classs
。
使用javap
命令
打开log.txt
魔数与 class 文件版本
常量池
访问标志
类索引、父类索引、接口索引
字段表集合
方法表集合
属性表集合
然后JVM
就可以读取这个User.class
文件进行解析等一系列的操作。
以上就是我们的Java
文件到 class 文件。
后续还会更新一系列 JVM 相关文章,敬请期待~
推荐阅读:
关注公众号“Java 后端技术全栈”
免费获取 500G 最新学习资料
![](https://static001.geekbang.org/infoq/a7/a781d09e6a887eb563994b67eea6fa57.png)
版权声明: 本文为 InfoQ 作者【田维常】的原创文章。
原文链接:【http://xie.infoq.cn/article/a121bd1ad5691d65c55c2040b】。文章转载请联系作者。
评论