java编译过程

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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?"成功":"失败");
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值