JavaWeb技术内幕四:Javac编译原理
微信公众号【Java技术江湖】一位阿里 Java 工程师的技术小站。(关注公众号后回复”Java“即可领取 Java基础、进阶、项目和架构师等免费学习资料,更有数据库、分布式、微服务等热门技术学习视频,内容丰富,兼顾原理和实践,另外也将赠送作者原创的Java学习指南、Java程序员面试指南等干货资源)
Java代码需要编译成class文件然后运行在JVM中。
# Javac是什么
javac是一种编译器,把java源代码转换成jvm能够识别的class文件。然后有JVM再把JVM语言转换成当前及其能够识别的机器语言。
Java语言屏蔽了目标及其相关的细节,语言执行和平台无关,这一特点让Java很流行,最大的体现就是Android使用java语言开发。
javac的任务是把Java源码编译成class字节码,表面上看是二进制数字流,实际上只有JVM能识别它的真正含义
javac编译器的基本结构
javac编译器的作用就是将符合Java语言规范的源代码转换成字节码。
1 首先,读取源代码,按字节读取,识别语法关键词比如if else等,判断其是否合法,这一步就是词法分析 词法分析的结果就是从代码中找出一些规范的token流。就像一句话我们要知道哪些是标点,动词,名词等。 2 接着,对这些token进行语法分析,这一步是检查这些关键词组合在一起是不是符合Java的语言规范,比如if后面是否是boolean表达式。类似英语中判断主谓宾关系是否正确。 语法分析的结果就是形成一个符合java规范的抽象语法树,它把语言的主要词法组织在一起,对这个语法树后面可以根据新的规则重组。这也是编译器的关键所在(重组成其他语言) 3 语义分析开始时已经不存在语法问题了,但是语义不一定正确,语义分析主要把复杂难懂的语法转为更简单的语法,类似于把文言文转换为白话文,或者注解一些成语。 也就是我们让一个句子既通顺又易懂。 语义分析的结果是复杂语法编程简单语法,比如foreach编程for循环,以及注解等,最后形成一个注解过后的抽象语法树。 4 最后,通过字节码生成器生成字节码,经过注解的抽象语法树生成字节码。就像是把中文翻译为英文
javac工作原理分析
词法分析器
生成token流
语法分析器
生成语法树
语义分析器
语法分析器生成的语法树太粗糙了,离字节码还有差距,我们要在此基础上做一些处理,比如给类加上默认构造函数,检查类型匹配,检查操作可达,检查异常和语法糖等。
这些操作完成后就可以按照这个完整的语法树生成字节码了。
实际上,ide就是利用语义分析,才能检查出我们代码中的错误。
代码生成器
1 将java方法中的代码块转化为符合JVM语法的命令格式,由于JVM是基于栈操作的,所以必须是入栈出栈的命令序列
。
2 按照JVM的文件组织个事将字节码输出到以class为扩展名的文件中。
设计模式值访问者模式
编译原理之自动机
在词法,语法分析的过程中,是如何进行的呢?一句话,程序语言是怎么形成的,其解析过程就是其“逆袭”的过程。
这就到了形式语言和自动机的舞台。
形式语言:按一定规律构成的句子或符号串的有限或无限的集合,是为了描述语言的一种理论模型。它只考虑语法,词法,而不考虑语义。
在形式语言中,有字母表,有状态集合,有从字母到字符串的规则,这其中包含,文法。字母表中的字母按照文法构成句子。文法又有不同的要求等级,对应的可以构成不同的语言,例如三型文法,构成正则语言。计算机语言学中为了识别文法构成的不同,引入自动机,把自动机作为语言识别器,用来研究各种形式语言。
总之,形式语言,自动机都是编译程序拿来检测程序设计语言的工具。我们只要明白这个就够了。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Java 代码----------------LeetCode------------ 53. 最大子序和
这道题本来是能做出来的,但是还是遗憾收场,我分析了之所以这样,是因为我做题时又乱了阵脚,没有秉承先思考这道题的思路,再往具体的算法上靠近的规则,这是一道动态规划类的题,它求的最大子序列,也是一步一步的推出来的,它的下一步是由上一步推出来的。对于这类题,你要看的我感觉就不必太多,你要着眼的就是最初的那数组的前几个,分析它们是否满足最大子序列然后就可以类推到一个更长的数组。 public int maxSubArray(int[] nums) { int[] dp = new int[nums.length]; dp[0] = nums[0]; int max = dp[0]; for (int i = 1, length = nums.length; i <length ; i++) { // 加入数组只有两个元素,那么它们要比的就是两个元素的和的大小和第一个元素和第二个元素的大小比较,首先你要明白,如果第一/二个元素是负数,那么加上它就是累赘,就不是最大长度了,所以你要判断它的第一/二个元素是否为负。 dp[i] = Math.max(dp[i-1]+nums[i],nums[i...
- 下一篇
Spring AOP总结
我们的程序从编写到执行,单个模块一般都是从上到下、垂直、连续的。 AOP是一种“横切”技术,能够在合适的地方“拦腰截断”、插入一些“代码”,使得原有功能进行增强。 为什么需要AOP 当我们要进行一些日志记录、权限控制、性能统计等时,在传统应用程序当中我们可能在需要的对象或方法中进行,而且比如权限控制、性能统计大部分是重复的,这样代码中就存在大量重复代码,即使有人说我把通用部分提取出来,那必然存在调用还是存在重复,像性能统计我们可能只是在必要时才进行,在诊断完毕后要删除这些代码;还有日志记录,比如记录一些方法访问日志、数据访问日志等等,这些都会渗透到各个要访问方法中;还有权限控制,必须在方法执行开始进行审核,想想这些是多么可怕而且是多么无聊的工作。如果采用Spring,这些日志记录、权限控制、性能统计从业务逻辑中分离出来,通过Spring支持的面向切面编程,在需要这些功能的地方动态添加这些功能,无需渗透到各个需要的方法或对象中;有人可能说了,我们可以使用“代理设计模式”或“包装器设计模式”,你可以使用这些,但还是需要通过编程方式来创建代理对象,还是要耦合这些代理对象,而采用Spring ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS8编译安装MySQL8.0.19