必威体育Betway必威体育官网
当前位置:首页 > IT技术

Javac编译器

时间:2019-08-17 02:15:20来源:IT技术作者:seo实验室小编阅读:53次「手机版」
 

java编译器

 javac编译器是把 *.java 文件转换为 *.class 文件,是一个前端编译器;对应着有一种把字节码转变为机器码的编译器,称为JIT编译器(Just In Time Compiler),比如 HotSpot VM 的C1、C2编译器;把 *.java 文件编译成机器码的编译器称为静态提前编译器;

Javac编译器编译的过程可以为3个过程:

  1、解析与填充符号表:

    这个过程又可以细分为词法分析、语法分析和填充符号表;

    词法分析:词法分析是将源代码的字符流转变为标记(Token)集合,单个字符是程序编写过程的最小元素,而标记则是编译过程的最小元素,关键字、变量名、字面量、运算符都可以成为标记。

    语法分析:语法分析是根据Token序列构造抽象语法树的过程,抽象语法树(Abstract Syntax Tree)是一种用来描述程序代码语法结构的树形表示方式,语法树的每一个节点都代表着程序代码中的一个语结构。

    符号表(symbol Tree):符号表是一组符号地址和符号信息构造的表格,符号表登记的信息在编译的不同阶段都要用到。

  2、插入式注解处理器的注解处理:插入式注解器相当于编译器的插件,我们可以通过注解处理器读取、修改、添加抽象语法树中的任意元素。如果对抽象语法树进行了修改,编译器将会重新回到解析及填充符号表的过程重新处理,直到所有插入式注解处理器都没有再对语法树进行修改为止。

  3、语义分析与字节码生成过程:语法分析的主要任务是对结构上正确的源程序进行上下文有关性质的审核,保证源代码程序符合逻辑。

    语义分析又可以细分为 标注检查和数据及控制流分析:

      标注检查:标注检查检查的内容包括变量使用前是否被声明、变量与赋值之间的数据类型是否能够匹配,常量折叠(比如 int a = 1 * 2; 会处理为 int a = 3;)等等;

      数据及控制流检查:检查内容有程序局部变量在使用前是否有赋值、方法的每一条路径是否都有返回值,是否所有的受查异常都被正常的处理 等等;

    语法糖:指在计算机语言中添加某种语法,这种语法对语言的功能并没有影响,但是方便程序员使用;

    字节码生成:字节码生成是把前面各个步骤所生成的信息(语法树、符号表)转化成字节码写到磁盘的过程,在这个过程中还进行了不少代码添加和转换的工作,比如生成实例构造器和类构造器;

Java 语法糖

1、泛型与类型擦除:

  泛型是JDK 1.5 的一项新增特性,它的本质是参数化类型的应用,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口和泛型方法。

  Java的泛型是一种伪泛型,它只存在于程序的源代码中,在编译后的字节码文件中,就已经替换为原来的原生类型。

2、自动拆箱、装箱和遍历循环:  

  自动装箱、自动拆箱反编译后对应包装类的包装、还原方法;

  遍历循环 反编译后对应 迭代器实现;

  变长参数 反编译后 变成了一个数组类型的参数;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

// 以下是源代码,包含了泛型,自动装箱,自动拆箱、遍历循环、变长参数共5种语法糖

List<integer> list = Arrays.asList(12345);

int sum = 0;

for (int i : list) {

    sum += i;

}

System.out.println(sum);

//反编译后的源代码

List list = Arrays.asList(new Integer[] {

                nullnullnullnull,

                (new Integer[5][3] =

                (new Integer[5][2] =

                (new Integer[5][1] =

                (new Integer[5][0] = Integer.valueOf(1)).valueOf(2)).valueOf(3)).valueOf(4)).valueOf(5) });

int i = 0;

for (Iterator iterator = list.iterator(); iterator.hasNext(); ) {

    int j = ((Integer)iterator.next()).intValue();

    i += j;

System.out.println(i);

3、自动装箱的陷阱:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

// 源代码

Integer a = 1;

Integer b = 2;

Integer c = 3;

Integer d = 3;

Integer e = 321;

Integer f = 321;

Long g = 3L;

         

System.out.println(c == d);

System.out.println(e == f);

System.out.println(c == (a + b));

System.out.println(c.equals(a + b));

System.out.println(g == (a + b));

System.out.println(g.equals(a + b));

// 反编译后的代码

Integer integer1 = Integer.valueOf(1);

Integer integer2 = Integer.valueOf(2);

Integer integer3 = Integer.valueOf(3);

Integer integer4 = Integer.valueOf(3);

Integer integer5 = Integer.valueOf(321);

Integer integer6 = Integer.valueOf(321);

Long l = Long.valueOf(3L);

         

System.out.println((integer3 == integer4));

System.out.println((integer5 == integer6));

System.out.println((integer3.intValue() == integer1.intValue() + integer2.intValue()));

System.out.println(integer3.equals(Integer.valueOf(integer1.intValue() + integer2.intValue())));

System.out.println((l.longValue() == (integer1.intValue() + integer2.intValue())));

System.out.println(l.equals(Integer.valueOf(integer1.intValue() + integer2.intValue())));

// 运行结果

true

false

true

true

true

false

//说明

1. 包装类的 “==” 运算在遇到算术运算符会自动拆箱

2. 包装类的 equals 方法先会判断比较的类型是否 instanceof 包装类

3. 当Integer,Long包装类在自动装箱时如果值在 -128 127 之间时会共享缓存值

 4、条件编译

javac编译器会把条件分支中永远不会执行的分支消除掉。

如果有想学习java的程序员,可来我们的java学习扣qun:830783865,免费送java的视频教程噢!我每晚上8点还会在群内直播讲解Java知识,欢迎大家前来学习哦。

相关阅读

[下载篇]VC++ 2010 Express 学生版 NCRE考试编译器

网盘下载地址[无密码] 2018年 NCRE考试 C++\C语言考试 改为 VC++ 2010 Express !!!!!!! 如果需要,请下载! 6VPJ7-H3CXH-HBTPT-X4T74-3YVY

GCC编译器简明教程(Linux下C语言开发环境的搭建)

GCC编译器简明教程(Linux下C语言开发环境的搭建) 市面上常见的Linux都是发行版本,典型的Linux发行版包含了Linux内核、桌面环境(例如

编译原理——一个编译器的各个步骤的介绍

一个编译器的结构分为分析部分(编译器的前端)和综合部分(编译器的后端)。 编译器的前端:把源程序分解成为多个组成要素,并在这些要素之

DOSBox0.74以及汇编编译器的安装使用(虚拟)64位

64位安装和使用方法:首先在D盘或其他盘(最好不要在C盘)新建一个名为 masm 的文件夹(名字可以任意,建议用masm).从https://pan.baidu.c

VS2015环境搭建以及QT编译器和调试器配置

简述 之前介绍过 Qt5.x 的环境搭建,5.7 开始支持 VS2015,为了使用新的开发环境(典型的强迫症),不得不再次进行 Qt5.7 + VS2015 的环境

分享到:

栏目导航

推荐阅读

热门阅读