1. 概述

本教程将介绍javac工具,并说明如何使用它将Java源文件编译为类文件。我们将从javac命令的简短描述开始,然后通过分析其各种选项深入探讨该工具。

2. javac命令

执行javac工具时,可以指定选项和源文件:

javac [options] [source-files]

其中[options]表示控制工具操作的选项,[source-files]表示要编译的一个或多个源文件。所有选项都是可选的。源文件可以直接作为javac命令的参数指定,也可以保存在参数文件中(稍后说明)。注意:源文件应按照其包含类型的完全限定名对应的目录层次结构排列

javac的选项分为三类:标准选项、交叉编译选项和额外选项。本文将重点介绍标准和额外选项。交叉编译选项用于在编译器环境不同的JVM实现上编译类型定义,属于不常用场景,本文不涉及。

3. 类型定义

首先介绍用于演示javac选项的类:

public class Data {
    List<String> textList = new ArrayList();

    public void addText(String text) {
        textList.add(text);
    }

    public List getTextList() {
        return this.textList;
    }
}

源代码位于文件com/baeldung/javac/Data.java中。注意:本文使用*nix风格的文件分隔符,在Windows系统上需使用反斜杠(\\)代替正斜杠(/)。

4. 标准选项

javac命令最常用的标准选项是-d指定生成类文件的目标目录。如果类型不属于默认包,会创建反映包名的目录结构来存放该类型的类文件。

在包含前述目录结构的目录中执行以下命令:

javac -d javac-target com/baeldung/javac/Data.java

javac编译器将生成类文件javac-target/com/baeldung/javac/Data.class。注意:在某些系统上,javac不会自动创建目标目录(本例中为javac-target),可能需要手动创建。

其他常用选项包括:

  • -cp(或-classpath--class-path
    指定编译源文件所需类型的查找位置。若未设置此选项且CLASSPATH环境变量未定义,则使用当前工作目录(如上例所示)。

  • -p(或--module-path
    指定必需应用模块的位置。仅适用于Java 9及以上版本——参考Java 9模块系统教程

若想了解编译过程细节(如加载了哪些类、编译了哪些类),可使用-verbose选项。

最后一个要介绍的标准选项是参数文件。无需直接向javac传递参数,可将参数存储在参数文件中。这些文件名以@字符为前缀,用作命令参数。

javac遇到以@开头的参数时,会将后续字符解释为文件路径,并将文件内容展开为参数列表。参数文件中的参数可用空格或换行符分隔。

假设在javac-args目录中有两个文件optionstypes,内容如下:

options文件:

-d javac-target
-verbose

types文件:

com/baeldung/javac/Data.java

执行以下命令可编译Data类型并在控制台输出详细信息:

javac @javac-args/options @javac-args/types

也可将所有参数存储在单个文件中。假设javac-args目录下有arguments文件:

-d javac-target -verbose
com/baeldung/javac/Data.java

执行以下命令可实现与前述双文件相同的效果:

javac @javac-args/arguments

注意:本节仅介绍最常用选项。完整标准选项列表请参考官方文档

5. 额外选项

javac的额外选项是非标准选项,特定于当前编译器实现,未来可能变更。因此不详细讨论这些选项,但有一个非常实用的选项值得介绍:-Xlint。其他额外选项的完整描述请参考此链接

-Xlint选项允许在编译时启用警告。命令行中指定该选项有两种方式:

  • -Xlint
    触发所有推荐警告
  • -Xlint:key[,key]
    启用特定警告

以下是几个实用的-Xlint键:

  • rawtypes
    警告原始类型的使用
  • unchecked
    警告未检查操作
  • static
    警告从实例成员访问静态成员
  • cast
    警告不必要的类型转换
  • serial
    警告可序列化类缺少serialVersionUID
  • fallthrough
    警告switch语句中的fallthrough情况

javac-args目录创建xlint-ops文件:

-d javac-target
-Xlint:rawtypes,unchecked
com/baeldung/javac/Data.java

执行以下命令:

javac @javac-args/xlint-ops

将看到rawtypesunchecked警告:

com/baeldung/javac/Data.java:7: warning: [rawtypes] found raw type: ArrayList
    List<String> textList = new ArrayList();
                                ^
  missing type arguments for generic class ArrayList<E>
  where E is a type-variable:
    E extends Object declared in class ArrayList
com/baeldung/javac/Data.java:7: warning: [unchecked] unchecked conversion
    List<String> textList = new ArrayList();
                            ^
  required: List<String>
  found:    ArrayList
...

6. 结论

本教程介绍了javac工具,展示了如何使用选项管理典型编译过程。实际开发中,我们通常使用IDE或构建工具编译程序,而非直接依赖javac。但深入理解该工具有助于在高级场景中自定义编译过程。

本教程源代码可在GitHub获取。


原始标题:Compiling Java *.class Files with javac