JVM 真香系列:轻松理解 class 文件到虚拟机(上)
关注“Java 后端技术全栈”
回复“000”获取大量电子书
认识 JVM
什么是 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
安装版本等。
认识 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
编译过程
这个 javac 命令过程到底干了些什么呢?
javac
背后大致做了这些操作
这个流程
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 最新学习资料
版权声明: 本文为 InfoQ 作者【田维常】的原创文章。
原文链接:【http://xie.infoq.cn/article/a121bd1ad5691d65c55c2040b】。文章转载请联系作者。
评论