JVM(一):源文件的转变
JVM(一):源文件的转变
本文讲述一个.java源文件是如何经过javac编译器的一系列操作变为.class文件的.
编译
说到编译,大家都能想到是编译器经过一系列方法将源代码转变为目标机器代码,但Java作为一个平台无关性语言,前端编译的主要作用是将源代码转变为JVM能识别出的语言,而具体与机器相关的机器代码生成由后续JVM自己掌控.
Java中的编译分为前端编译和后端编译两种,本文讲解的主要是前端编译,后端编译是JVM运行期的时候将Java代码编译为本地机器码的过程,因为Java是一门动态性语言,大部分的代码优化都是放在后端编译中,展开来讲篇幅比较长,因此具体的优化方式放在后续文章再详细描述.
javac
如上文所说,javac编译器能做到将一门高级语言转变为JVM能识别出的语言,而若要完成这些功能需要javac拥有哪些模块和功能,下面就由笔者来为大家讲解一下.
ps:因笔者对汇编语言也不甚了解,所以讲述的编译细节也不是十分具体,此外若有错误,请大家积极指出,谢谢!
javac的构成
javac的构成<figcaption style="line-height: inherit; margin: 0px; padding: 0px; margin-top: 10px; text-align: center; color: rgb(153, 153, 153); font-size: 0.7em;">javac的构成</figcaption>
词法分析
词法分析的作用是将源代码一个一个字节的读取出来,识别出哪些字节是Java语言中的关键字,如if,while,for等,哪些是程序员自定义字节,如a,b等.举例来说,Java中的一句
1int a = b + 1;
句中就包含了 int , a , = , b , + , 1 , ;七个字节.
语法分析
语法分析的作用是对上一步得到的Token字节流进行分析,验证其是否符合Java语言规范,如在int后面是否紧跟着一个符合Java命名规范的变量名.=前的变量是否可赋值等等.
在这一步会得到一个语法树,其功能是将语言的主要词法用一个结构化的形式组织在一起.
语义分析
在上一步得到了一个语法树,但其无法保证这个语法树是逻辑正确的,例如coder可能会为一个还没有声明的变量赋值,这个错误在前两步是无法检查出的,只有在这一步通过语义分析才能检查出错误.另外在这一步还会对语法糖进行解糖(desugar)操作,将复杂难懂的语法转变为简单易懂的语法.
具体Java中有哪些语法糖,每个语法糖对应的基础结构留待下篇文章再详细讲解.
语法糖:计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。(来自百度百科)
例如Java中的自动拆装箱,foreach循环等都属于语法糖的范畴.
字节码生成
字节码生成是javac编译过程的最后一个阶段.其作用是将前面各个步骤生成的信息转化为字节码写到磁盘中,生成.class文件,也宣布了整个编译过程的结束.
总结
本文主要描述Java中的前端编译,叙述了Java源代码是如何经过 词法分析,语法分析,语义分析,字节码生成 4个步骤变为.class文件的.具体的实现细节,笔者因对汇编不是十分了解,且认为不是十分重要而没有具体展开,若读者有兴趣,可以自行翻阅<<深入理解Java虚拟机>>进行学习.
iceWang公众号<figcaption style="line-height: inherit; margin: 0px; padding: 0px; margin-top: 10px; text-align: center; color: rgb(153, 153, 153); font-size: 0.7em;">iceWang公众号</figcaption>
文章在公众号"IceWang"第一手更新,有兴趣的朋友可以关注公众号,第一时间看到笔者分享的各项知识点,谢谢!笔芯.
本系列文章主要借鉴自<深入分析JavaWeb技术内幕>和<深入理解Java虚拟机-JVM高级特性与最佳实践>.