java编译过程

本文详细解释了Java编译器将源文件转换为class文件的过程,包括词法分析器识别并创建词法单元,语法分析器构建抽象语法树,以及注解处理器、语义分析和代码生成器的作用。最后提到使用Java代码调试编译过程的方法。
摘要由CSDN通过智能技术生成

java编译器将 java 源文件转换成 class 文件的过程。

(1)词法分析器

作用:将Java源文件的字符流转变成对应的Token流

每个词法单元(token)都有一个类型(token type)和一个值(token value)。例如:

**词法单元类型**可能包括:
- 关键字(如 `if`、`else`、`for`、`class` 等)
- 标识符(变量名或函数名)
- 运算符(如 `+`、`-`、`*`、`/`、`=` 等)
- 分隔符(括号、大括号 `{}`、方括号 `[]`、圆括号 `()`,以及逗号 `,`、冒号 `:`、分号 `;` 等)
- 字面量(整数、浮点数、字符串等)
- 注释
- 特殊符号(如EOF,表示文件结束)

**词法单元值**则是对应的文本内容。

举例说明:

假设有一个简单的Java源代码片段:
```java
int main() {
    int x = 5;
    if (x > 3) {
        System.out.println("Hello, World!");
    }
}
```

经过词法分析后,可能会产生如下形式的结果:

1. `(int, "int")`
2. `(identifier, "main")`
3. `(symbol, "(")`
4. `(symbol, ")")`
5. `(symbol, "{")`
6. `(int, "int")`
7. `(identifier, "x")`
8. `(symbol, "=")`
9. `(integer_literal, "5")`
10. `(symbol, ";")`
11. `(keyword, "if")`
12. `(symbol, "(")`
13. `(identifier, "x")`
14. `(symbol, ">")`
15. `(integer_literal, "3")`
16. `(symbol, ")")`
17. `(symbol, "{")`
18. `(identifier, "System")`
19. `(symbol, ".")`
20. `(identifier, "out")`
21. `(symbol, ".")`
22. `(identifier, "println")`
23. `(symbol, "(")`
24. `(string_literal, "\"Hello, World!\"")`
25. `(symbol, ")")`
26. `(symbol, ";")`
27. `(symbol, "}")`
28. `(symbol, "}")`
29. `(EOF, "")` (表示文件结束)

这里的每一组 `(类型, 值)` 就是词法分析器生成的一个个词法单元。这些单元后续会被传递给语法分析器进行进一步的语法结构分析。

(2)语法分析器

作用:将Token流组建成更加结构化的语法树

下面一个例子解析

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

经过Java编译器的词法分析和语法分析后,得到的抽象语法树(AST)的大致结构可能是这样的:
 CompilationUnit
   └── ClassDeclaration
       ├── Modifier (public)
       ├── Identifier (HelloWorld)
       ├── ClassBody
       │   └── MethodDeclaration
       │       ├── Modifier (public)
       │       ├── Modifier (static)
       │       ├── Type (void)
       │       ├── Identifier (main)
       │       ├── FormalParameters
       │       │   └── Parameter
       │       │       ├── Type (String[])
       │       │       └── Identifier (args)
       │       └── MethodBody
       │           └── StatementExpression
       │               ├── MethodInvocation
       │               │   ├── Name (System.out)
       │               │   └── ArgumentList
       │               │       └── StringLiteral ("Hello, World!")
       │               └── SemiColon (;)

(3)插入式注解处理器

下篇专门写这个功能,

        简介:插入式注解处理器可以帮助我们在javac编译期修改抽象语法树(AST),进而改变生成的class文件。

(4)语义分析器
        1)检查语义的合法性并进行逻辑判断

    如以下几点:

  • 变量的类型是否匹配
  • 变量在使用前是否已经完成初始化
  • 能够推导出泛型方法的参数类型
  • 字符串常量的合并
  • 去掉无用的代码
  • 变量的自动转换
  • 去除语法糖
(5)代码生成器

代码生成器将注解语法树转化为字节码

字节码生成是 javac 编译过程的最后一个阶段,将上面步骤所生成的注解语法树、符号表等信息转化成字节码指令写到 class 文件中。

(6)使用java代码调试(编译的过程)

        1)javac命令可以编译源文件,

        2)java代码类JavaCompiler也能编译源文件

java代码编译源文件的代码如下:

package com.dh.testJavac;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

class TestJavac {

    /**
     * 默认找不到com.sun.tools.javac.processing.JavacProcessingEnvironment
     * 需要在idea->文件->项目结构->SDK->类路径->添加C:\Program Files\Java\jdk1.8.0_171\lib\tools.jar进去
     * @param args
     */
    public static void main(String[] args) {
        JavaCompiler systemJavaCompiler = ToolProvider.getSystemJavaCompiler();
//        com.sun.tools.javac.processing.JavacProcessingEnvironment
        int r = systemJavaCompiler.run(null, null, null, "E:\\ideaWorkSpace\\shdhv3WorkSpace\\shdhv3\\src\\test\\java\\com\\dh\\testJavac\\ComClass.java");
        System.out.println(r==0?"成功":"失败");
    }


}

Java编译过程是一个将Java源代码文件转换成Java虚拟机(JVM)可以执行的字节码文件的过程。这个过程大致可以分为以下几个步骤: 1. **源代码文件的编写**:首先,我们需要用文本编辑器编写Java源代码文件,并保存为`.java`扩展名的文件,比如`Example.java`。 2. **编译**:使用Java编译器(javac)对源代码文件进行编译编译器会检查代码是否有语法错误,并将其编译成`.class`扩展名的字节码文件。例如: ```bash javac Example.java ``` 这个命令会生成一个`Example.class`文件,该文件包含了Java虚拟机可以执行的字节码。 3. **字节码验证**:Java虚拟机在加载类文件时会进行字节码验证,确保字节码符合Java虚拟机规范,并且不会造成系统安全风险。 4. **类加载**:JVM会加载字节码文件到内存中,准备执行程序。类加载器会从文件系统、网络或其它来源加载`.class`文件,并创建相应的类对象。 5. **字节码解释执行**:当类被加载后,JVM通过解释器逐条将字节码转换成机器码执行。对于JIT(Just-In-Time)编译的JVM来说,它还会在运行时将热点代码编译成更为高效的本地代码,提高程序运行效率。 下面是一个简单的Java编译过程例子: 1. 假设我们有如下的Java源代码(`HelloWorld.java`): ```java public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } ``` 2. 使用javac编译编译这个文件: ```bash javac HelloWorld.java ``` 这个命令会在当前目录下创建一个`HelloWorld.class`文件。 3. 然后,我们可以使用Java命令来执行这个编译后的字节码文件: ```bash java HelloWorld ``` 执行后,你会在控制台看到输出:"Hello, World!"。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值