Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java编译器的内部结构_Java_Javacompiler - Fatal编程技术网

Java编译器的内部结构

Java编译器的内部结构,java,javacompiler,Java,Javacompiler,我从事Java已有8年多了 上周,在我公司的一次小型会议上,我的一位同事问我,Java编译器到底是如何工作的?我没有回答 我试着解释,就像Java编译器一个接一个地获取语句,并将它们转换为字节码,而不是针对任何OS,而是针对JVM 没有人对这个答案感到满意,即使是我 现在主要的问题是java编译器到底是如何工作的。i、 e.编译Java文件时,编译器将完成多少步骤、阶段或阶段 Java的编译器体系结构是什么 如果在同一个.Java文件中有多个Java类,该怎么办。那么将编译多少类 如果有指向未编

我从事
Java
已有8年多了

上周,在我公司的一次小型会议上,我的一位同事问我,
Java编译器
到底是如何工作的?我没有回答

我试着解释,就像Java编译器一个接一个地获取语句,并将它们转换为字节码,而不是针对任何
OS
,而是针对
JVM

没有人对这个答案感到满意,即使是我

现在主要的问题是java编译器到底是如何工作的。i、 e.编译
Java
文件时,编译器将完成多少步骤、阶段或阶段

Java的编译器体系结构是什么

如果在同一个.Java文件中有多个
Java类
,该怎么办。那么将编译多少类

如果有指向未编译Java类的导入呢?那么应该编译还是忽略未编译的类

我在谷歌上搜索了半天多,所有人都给出了和我给同事们一样的答案

但最后我找到了一些有用的教程

但本教程的内容也不太深入,我无法想象该教程

我仍然不满足,也不渴望从你那里学到更多

因此,如果有人比我和上面的博客更了解一些东西,那么我可以通过这些东西直观地了解
Java编译器的内部架构,请向我解释。

一些基本步骤:

  • 解析:读取一组*.java源文件并映射生成的令牌 序列到AST(抽象语法树)-节点
  • 输入:在符号表中输入定义的符号
  • 流程注释:如果请求,可以在中找到流程注释 指定的编译单元
  • 属性:语法树的属性。此步骤包括名称 分辨率、类型检查和恒定折叠
  • 流:对上一步中的树执行数据流分析。 这包括检查分配和可达性
  • desugar:重写AST并翻译掉一些语法糖
  • 生成:生成源文件或类文件
  • 详情如下:

  • Lex-将源文件分解为单个单词或标记
  • 解析-分析程序的短语结构
  • 语义动作——构建一个对应于每个短语的抽象语法树
  • 语义分析-确定每个短语的含义,将变量的使用与其定义联系起来,检查表达式的类型,请求翻译每个短语
  • 框架布局-以机器相关的方式将变量、功能参数等放入激活记录(堆栈框架)中
  • 翻译-生成中间表示树(IR树),表示法 这与任何特定的源语言或targetmachine体系结构无关
  • 规范化-从表达式中提取副作用,并清理条件分支,以方便下一阶段
  • 指令选择-将IR树节点分组为对应于目标机器指令操作的集群
  • 控制流分析-将指令序列分析成控制流图,该图显示程序可能的所有可能的控制流 当它执行时跟随

  • 数据流分析-通过程序变量收集有关信息流的信息;例如,活动性分析计算每个程序变量保存仍然需要的值(是活动的)的位置

  • 寄存器分配-选择一个寄存器来保存程序使用的每个变量和临时值;变量不能同时存在 可以共享同一寄存器

  • 代码排放-将每个机器指令中的临时名称替换为 机器寄存器

  • 有一本好书:

    Java中的现代编译器实现

    您可能需要查看javac代码:


    编译器有不同的步骤,但以下是最重要的步骤:

    词汇分析 第一步是词汇分析。基本上,这个步骤从java代码中提取标记(关键字、运算符、分隔符、注释、变量名…)

    语法分析(解析器) 第二步是语法分析。标记作为词法分析的输入,并组合成表达式和指令

    优化和字节码转换 最后一个宏步骤是将上一个步骤转换为字节码。在这里,代码可以修改为与原始代码等效,但效率更高


    注意:此过程不仅与java相关,而且对所有编译器都是通用的。也包括不生成中间字节代码而是生成机器代码的编译器(如C或C++编译器)

    通常,有一些工具可以创建词法分析器和语法分析器,因为这些步骤在不同语言之间有许多通用部分

    提供了一个开源的词法分析器 一个有用的语法分析器是


    两种语言都是C和C++的,它们是最常用的语言来创建编译器(java和其他语言),但是也有类似的替代方案用于其他编程语言(在< <强> >另一种语言中创建编译器<强>,而不是<强> >另一种语言>。基本上,编写编译器所用的语言与编译器编译的语言无关。

    JVM规范非常详细:…@Würgspaß是的,你绝对正确。但是你自己看看文档就可以了。它相当复杂,需要花很多时间去理解。现在一天的时间是我们没有的。所以我想这里有些人可能已经有了同样的问题,可能已经有了答案