本文参考资料:
深入理解JAVA虚拟机:JVM高级特性与最佳实践/周志明著
JAVA虚拟机精讲/高翔龙编著
如有描述不正确之处,欢迎大家指出
共勉
在上一篇《Java体系结构》中,我们提到了Java的一次编译处处运行。而支持这种一次编译处处运行的思想的就是各平台通用的字节码。所以这一篇我们深入接触一下字节码的编译原理。
想了解上一篇内容的读者烦请移步: 《Java体系结构》
一个完成的Java程序的编写到执行的结果如下图所示:
我们可以看到源代码经过前端编译器的编译成为了平台通用的字节码,从而实现一次编译处处运行。但是这里所用的前端编译器到底是什么呢?
很多人可能会想到javac ,没错javac确实是可以实现上述功能的一种编译器,但是并不是只有这一种。
当我们使用工具例如Eclipse来开发时,Eclipse有内置的前端编译器------ECJ(Eclipse Compiler for Java)。ECJ是自主研发的,而且功能很优秀,完全可以和javac相媲美。
我们来看一下javac和ECJ的区别在哪里?
大致了解了以上两种编译器,现在我们详细地来了解一下javac编译器的编译原理,也可以说是javac的编译过程。
首先要搞清楚javac负责的是一个完成Java程序运行的其中的部分步骤。
具体主要是将源代码编译为一个有效的字节码文件。
javac的编译过程图解(图来自博客园用户wade&luffy):
具体描述为:
- 词法分析
- 语法分析
- 语义分析
- 生成字节码
词法分析:将源码中的关键字和标识符等内容转换成符合Java语法规范的Token序列,然后按照指定的顺序规则进行匹配校验。
语法分析:将词法分析后的Token序列整合为一棵结构化的抽象语法树。
语义分析:完善扩充语法树。
最后一步则得到了javac需要做到的结果就是生成了字节码文件。
到这里我们的javac编译器就光荣完成使命啦。
下面就由jvm来对字节码文件进行解释/编译从而得到各平台本地的机器指令来执行了。
如果有兴趣的话,我们考虑进一步深入了解javac的源码。
因为在2006年推出JDK1.6版本之前,Sun公司已经宣布要将JDK开源了,在随后的一年多时间里,陆续公开了JDK各部分的源码,并且建立OpenJDK组织对源码进行独立管理。所以我们是可以从网上拿到JDK源码的。具体怎么下载这里笔者就不赘述了,还是直接努力地引导大家通过文章来进行一定程度的理解吧,求知欲强想亲自下载下来看源码的读者劳烦自己搜索方法。
ps:笔者暂时啃不下去javac的源码,改天吧!