javac编译原理

每个人在学习Java的时候都配置过环境变量,检查是否配置成功的时候,我们总会在命令行敲入两个命令,一个是 java,一个是 javac。刚开始我们都不知道这两个命令代表的含义,随着学习的深入,我们知道了 java 命令就是检查是否找得到运行环境,而 javac 就是编译Java源代码的编译器。现在,深入探索一下 javac 这个神奇的编译器,看看它的背后到底是什么。

javac的流程

 javac是一种编译器,能够将一种语言规范转化成另一种语言规范。javac的任务是将Java源代码语言转化成JVM能够识别的语言,然后由JVM将JVM语言再转化成当前机器能够识别的机器语言。Java语言向开发者屏蔽了很多与目标机器相关的细节,使得Java语言的执行与平台无关。

 如下图所示,javac的任务就是将Java源码编译成Java字节码(二进制流),也就是JVM能够识别的语言:

javac编译原理

 要清楚javac编译器有哪些工作模块或者基本结构,首先要知道其工作流程,通过工作流程去剖析细节。下面javac的工作流程图:

javac编译原理

  • 第一步,词法分析:按字节读取源码,找出这些字节码文件中我们定义的语法关键词。例如:if,else,for,while等关键词。识别出哪些if是合法的,哪些不是。

    通过词法分析,从源码中找出了一些规范化的Token流。例如:找出一个句子里面的标点,主语,谓语,宾语,动词等等。

  • 第二步,语法分析:现在要做的就是对Token流做语法分析,检查这些关键词组合在一起是不是符合Java语言规范,如for循环格式是否正确等。

    通过语法分析形成了一个符合Java语言规范的抽象语法树。抽象语法树是一个结构化的语法表达形式,它的作用是把语言的主要词法用一个结构化的形式组织在一起。例如:离散数学中用数字来表达一些有复杂关系的物质世界,图,树等。

  • 第三步,语义分析:语义分析的主要工作是把一些难懂的,复杂的语法转化成更加简单的语法。例如:将难懂的文言文转化成易懂的白话文。

    语义分析的结果是将复杂的语法转化成最简单的语法,例如:将lambda表达式转成简单的数据结构,并加上注解。最后形成一个注解过后的抽象语法树,该语法树更接近目标语言的语法规则。

  • 第四步,代码生成器生成字节码:根据经过注解的抽象语法树生成字节码,也就是将一个数据结构转化成另一个数据结构。例如:将白话中文翻译成英文。

 javac的各个模块完成了将Java源代码转化成Java字节码的任务,所以javac主要有四个模块:词法分析器,语法分析器,语义分析器,代码生成器。

JDK中rt.jar、tools.jar和dt.jar作用
  • rt.jar 是Java基础类库,位于/jre/lib目录下,由应用程序类加载器(Application ClassLoader)加载:

javac编译原理

  • dt.jar是关于运行环境的类库,位于/lib目录下,由启动类加载器(Bootstrap Classloader)加载:

  • tools.jar是工具类库,编译和运行需要的都是toos.jar里面的类分别是sun.tools.java.; sun.tols.javac.,位于/jre/lib目录下,由启动类加载器(Bootstrap Classloader)加载:

javac编译原理