魔术桌
  • 更新日志
  • 新闻资讯
  • 数据资产
  • 网站导航
  • 订阅推荐
  • 商品推广
  • 日记
  • 摘录
  • 论文
  • 方案
  • 技术
  • 风格
  • 视觉
  • 原材料
  • 加工工艺
  • 元器件
  • 产品设备
  • 设计模式
  • 数据结构
  • 算法设计
  • 软件架构
  • 程序语言
  • 代码类库
  • 操作系统
  • 软件包
  • 健康
  • 环境
  • 社会
  • 道德
  • 法律
  • 经济
  • 政策
  • 更新日志
  • 新闻资讯
  • 数据资产
  • 网站导航
  • 订阅推荐
  • 商品推广
  • 日记
  • 摘录
  • 论文
  • 方案
  • 技术
  • 风格
  • 视觉
  • 原材料
  • 加工工艺
  • 元器件
  • 产品设备
  • 设计模式
  • 数据结构
  • 算法设计
  • 软件架构
  • 程序语言
  • 代码类库
  • 操作系统
  • 软件包
  • 健康
  • 环境
  • 社会
  • 道德
  • 法律
  • 经济
  • 政策
  • Package - Oracle JDK - 终端命令 - javac

文章摘要: 读取 Java 类和接口定义,并将它们编译为字节码和类文件。

简介

  • javac 命令读取用 Java 编程语言编写的类和接口定义,并将它们编译为字节码类文件。
  • javac 命令还可以处理 Java 源文件和类中的注释。

有两种方法可以将源代码文件名传递给 javac:

  • 对于少量源文件,请在命令行上列出文件名。
  • 对于大量源文件,请在文件中列出文件名,并用空格或换行符分隔。在 javac 命令中使用前面带有 at 符号 (@) 的列表文件名。

注释

  • 源代码文件名必须具有 .java 后缀,类文件名必须具有 .class 后缀,并且源文件和类文件都必须具有标识类的根名称。例如,名为 MyClass 的类将写入名为 MyClass.java 的源文件中,并编译为名为 MyClass.class 的字节码类文件。
  • 内部类定义会生成其他类文件。这些类文件具有由内部和外部类名组合而成的名称,例如 MyClass$MyInnerClass.class。
  • 将源文件排列在反映其包树的目录树中。例如,如果所有源文件都位于 /workspace 中,则将 com.mysoft.mypack.MyClass 的源代码放在 /workspace/com/mysoft/mypack/MyClass.java 。
  • 默认情况下,编译器将每个类文件放在与其源文件相同的目录中。您可以使用 -d 选项指定单独的目标目录。

格式

提示

javac [<选项>] [<源文件>] [<类>] [@argfiles]

选项

注释

标准选项

  • 编译器具有一组在当前开发环境中受支持的标准选项。
  • 另一组非标准选项特定于当前虚拟机和编译器实现,将来可能会更改。
  • 非标准选项以 -X 选项开头。

-help

  • 打印标准选项的概要。

-A <键>[=<值>]

  • 指定要传递给注释处理器的选项。这些选项不是由 javac 直接解释的,而是可供各个处理器使用。键值应为一个或多个标识符,用点 (.) 分隔。

-cp path -classpath path

  • 指定查找用户类文件以及 (可选) 注释处理器和源文件的位置。
  • 此类路径将覆盖 CLASSPATH 环境变量中的用户类路径。
  • 如果 CLASSPATH、-cp 和 -classpath 均未指定,则用户_类路径_为当前目录。
  • 如果未指定 -sourcepath 选项,则还会在用户类路径中搜索源文件。
  • 如果未指定 -processorpath 选项,则还会在类路径中搜索 annotation 处理器。

-Djava.ext.dirs=<目录>

  • 覆盖已安装扩展的位置。

-Djava.endorsed.dirs=<目录>

  • 覆盖已认可的标准路径的位置。

-d <目录>

  • 设置类文件的目标目录。该目录必须已存在,因为 javac 不会创建该目录。
  • 如果类是包的一部分,则 javac 会将类文件放在反映包名称的子目录中,并根据需要创建目录。
  • 例如:指定 -d /home/myclasses,并且类名为 com.mypackage.MyClass,则类文件为 /home/myclasses/com/mypackage/MyClass.class。
  • 例如:未指定 -d 选项,则 javac 会将每个类文件放在与生成该类文件的源文件相同的目录中。
  • 注意:-d 选项指定的目录不会自动添加到您的用户类路径中。

-deprecation

  • 显示已弃用成员或类的每次使用或重写的说明。如果没有 -deprecation 选项,javac 将显示使用或覆盖不推荐使用的成员或类的源文件的摘要。
  • -deprecation 选项是 -Xlint:deprecation 的简写。

-encoding <编码>

  • 设置源文件编码名称。
  • 如果未指定 -encoding 选项,则使用平台默认转换器。
  • 编码:UTF-8

-endorseddirs <目录>

  • 覆盖已认可的标准路径的位置。

-extdirs <目录>

  • 覆盖 ext 目录的位置。directories 变量是以冒号分隔的目录列表。将搜索指定目录中的每个 JAR 文件以查找类文件。找到的所有 JAR 文件都将成为类路径的一部分。

-g

  • 生成所有调试信息,包括局部变量。
  • 默认情况下,仅生成行号和源文件信息。

-g:none

  • 不生成任何调试信息。

-g:[<关键字列表>]

  • 仅生成某些类型的调试信息,由逗号分隔的关键字列表指定。
  • 关键字列表:source源文件调试信息,lines行号调试信息,vars局部变量调试信息。

-implicit:[<选项>]

  • 控制隐式加载的源文件的类文件的生成。
  • 选项:class要自动生成类文件,none要禁止生成类文件。
  • 如果未指定此选项,则默认为 automatically generate class files。在这种情况下,如果在执行注释处理时生成任何此类类文件,编译器会发出警告。
  • 当显式设置 -implicit 选项时,不会发出警告。

-J<选项>

  • 将选项传递给 Java 虚拟机(JVM),其中选项是 Java 启动器参考页面上描述的选项之一。
  • 例如,-J-Xms48m 将启动内存设置为 48 MB。

-nowarn

  • 禁用警告消息。
  • 此选项的操作与 -Xlint:none 选项相同。

-parameters

  • 将构造函数和方法的形参名称存储在生成的类文件中,以便 Reflection API 中的方法可以 java.lang.reflect.Executable.getParameters 检索它们。

-proc: [<选项>]

  • 控制是否完成注释处理和编译。
  • 选项:none表示编译时不进行Comments处理,only表示仅完成Comments处理不进行任何后续编译。

-processor class1 [,class2,class3...]

  • 要运行的注释处理器的名称。这将绕过默认的发现过程。

-processorpath <路径>

  • 指定查找注释处理器的位置。
  • 如果未使用此选项,则在类路径中搜索处理器。

-s <目录>

  • 指定放置生成的源文件的目录。
  • 该目录必须已存在,因为 javac 不会创建该目录。
  • 如果类是包的一部分,则编译器会将源文件放在反映包名称的子目录中,并根据需要创建目录。

-source <版本>

  • 指定接受的源代码版本。
  • 版本:
  • 1.3:编译器不支持断言、泛型或 Java SE 1.3 之后引入的其他语言功能。
  • 1.4:编译器接受包含 Java SE 1.4 中引入的断言的代码。
  • 1.5:编译器接受包含 Java SE 5 中引入的泛型和其他语言功能的代码。
  • 5:Synonym for 1.5. 1.5 的同义词。
  • 1.6:Java SE 6 中没有引入任何语言更改。但是,源文件中的编码错误现在报告为错误,而不是像 Java Platform, Standard Edition 的早期发行版那样报告为警告。
  • 6:Synonym for 1.6. 1.6 的同义词。
  • 1.7:编译器接受具有 Java SE 7 中引入的功能的代码。
  • 7:Synonym for 1.7. 1.7 的同义词。
  • 1.8:这是默认值。编译器接受具有 Java SE 8 中引入的功能的代码。
  • 8:Synonym for 1.8. 1.8 的同义词。

-sourcepath <源路径>

  • 指定用于搜索类或接口定义的源代码路径。
  • 与用户类路径一样,源路径条目在上下文中用冒号(:)在 Oracle Solaris 上和分号之间分隔,可以是目录、JAR 存档或 ZIP 存档。如果使用 packages,则目录或存档中的本地路径名必须反映 package 名称。

-verbose

  • 使用详细输出,其中包括有关加载的每个类和编译的每个源文件的信息。

-version

  • 打印版本信息。

-werror

  • 出现警告时终止编译。

-X

  • 显示有关非标准选项和退出的信息。

注释

交叉编译选项

  • 默认情况下,类是根据 javac 附带的平台的引导类和扩展类进行编译的。
  • 但 javac 也支持交叉编译,其中类是针对不同 Java 平台实现的引导和扩展类进行编译的。
  • 在交叉编译时使用 -bootclasspath 和 -extdirs 选项非常重要。

-target <版本>

  • 生成以虚拟机的指定版本为目标的类文件。
  • 类文件将在指定的目标和更高版本上运行,但不在 JVM 的早期版本上运行。有效目标是 1.1、1.2、1.3、1.4、1.5(也是 5)、1.6(也是 6)、1.7(也是 7)和 1.8(也是 8)。

-bootclasspath <引导类路径>

  • 针对指定的引导类集进行交叉编译。与用户类路径一样,引导类路径条目由冒号 (:)分隔,可以是目录、JAR 存档或 ZIP 存档。

-profile

  • 使用压缩配置文件时,此选项在编译时指定配置文件名称。例如:javac -profile compact1 Hello.java

源文件

  • 要编译的一个或多个源文件(例如 MyClass.java)。

类

  • 要处理注释的一个或多个类(例如 MyPackage.MyClass)。

@argfiles

  • 列出选项和源文件的一个或多个文件。这些文件不允许使用 -J 选项。

案例

# 编译多个源文件
javac Main.java Helper.java

# 指定类路径
javac -cp /usr/lib/java/commons.jar:. MyClass.java

# 指定输出目录
javac -d ./bin MyClass.java

# 包含调试信息
javac -g MyClass.java

# 忽略警告
javac -nowarn MyClass.java

# 显示详细信息
javac -verbose MyClass.java

# 使用源路径
javac -sourcepath /usr/src/java MyClass.java

# 使用不同的java版本
javac -source 1.7 -target 1.7 MyClass.java

# 编译注释处理程序
javac -processor com.example.MyProcessor MyClass.java

使用-Xlint选项启用或禁用警告

使用 -Xlint:name 选项启用警告_名称_,其中 name 是以下警告名称之一。请注意,您可以使用 -Xlint:-name: 选项禁用警告。

cast

  • 对不必要和冗余的强制转换发出警告。

classfile

  • 警告与类文件内容相关的问题。

deprecation

  • 对已弃用项目和API的使用发出警告。

dep-ann

  • 对使用 @deprecated Javadoc 注释记录但没有 @Deprecated 注释的项目发出警告。

divzero

  • 对常数整数 0 的除法发出警告。

empty

  • 对 if 语句之后的空语句发出警告。

fallthrough

  • 检查 switch 块中是否存在直通情况,并为找到的任何情况提供警告消息。
  • Fall-through case 是 switch 块中的情况,而不是块中的最后一个 case,其代码不包含 break 语句,从而允许代码执行从该 case 过渡到下一个 case。
  • 如果在编译此代码时使用 -Xlint:fallthrough 选项,则编译器会发出有关可能 fallthrough into case 的警告,并提供相关 case 的行号。

finally

  • 对无法正常完成的 finally 子句发出警告。

options

  • 对与使用命令行选项相关的问题发出警告。

overrides

  • 对有关方法覆盖的问题发出警告。

path

  • 对命令行上的无效路径元素和不存在的路径目录(关于类路径、源路径和其他路径)发出警告。

processing

  • 警告有关注释处理的问题。
  • 当您有一个具有注释的类,并且您使用的注释处理器无法处理该类型的异常时,编译器将生成此警告。

rawtypes

  • 对原始类型执行未经检查的操作时发出警告。

Serial

  • 警告可序列化类上缺少 serialVersionUID 定义。

static

  • 对与使用静态力学相关的问题发出警告。

try

  • 警告与使用 try 块相关的问题,包括 try-with-resources 语句。

unchecked

  • 提供 Java 语言规范强制要求的未选中的转换警告的更多详细信息。

varargs

  • 警告变量参数 (varargs) 方法的不安全使用,特别是那些包含不可修改参数的方法。

命令行参数文件

命令行参数文件是用于简化 javac 命令的工具,允许开发者将 javac 的参数列表放入一个或多个文件中,而不是直接在命令行中输入。以下是关于命令行参数文件的总结:

  • 目的:简化长或复杂的 javac 命令,使其更易于管理和执行。
  • 内容:参数文件可以包含 javac 的选项和源文件名,但不能包含 -J 选项。
  • 格式:参数文件中的参数可以用空格或换行符分隔。如果文件名包含空格,需要用双引号括起来。
  • 路径:参数文件中的文件名是相对于当前工作目录的,而不是参数文件的位置。不支持使用通配符和递归解释文件。
  • 使用方法:在 javac 命令中,通过在参数文件名前加上 @ 符号来引用参数文件。
  • 示例:
    • 单个参数文件:javac @argfile
    • 多个参数文件:分别创建选项文件(如 options)和源文件列表(如 classes),然后使用 javac @options @classes 来编译。
    • 带路径的参数文件:参数文件可以位于任意路径,但文件内的路径是相对于当前工作目录的。

注释处理

注释处理是 Java 编译器 javac 的一个特性,它允许在编译过程中检测和处理源代码中的注释。以下是关于注释处理的总结:

  • 集成:javac 直接支持注释处理,无需使用单独的命令 apt。
  • API 定义:注释处理器的 API 位于 javax.annotation.processing 和 javax.lang.model 包及其子包中。
  • 工作原理:
    • 除非使用 -proc:none 禁用,编译器会搜索可用的注释处理器。
    • 可以通过 -processorpath 指定搜索路径,默认使用用户类路径。
    • 注释处理器通过 META-INF/services/javax.annotation.processing.Processor 配置文件发现。
    • 可以通过 -processor 显式指定处理器。
  • 处理流程:
    • 编译器扫描源文件和类以查找注释。
    • 匹配的注释由相应的处理器处理。
    • 处理器可以声明它们处理的注释,防止其他处理器处理相同的注释。
    • 如果处理器生成新的源文件,将启动新一轮的注释处理。
    • 处理过程重复,直到不再生成新的源文件。
    • 最后,处理器被最后一次调用以完成剩余工作,然后编译器编译所有源文件,除非使用 -proc:only。
  • 隐式加载的源文件:
    • 编译器可能需要隐式加载额外的源文件来编译指定的源文件集。
    • 这些隐式加载的源文件目前不受注释处理的影响。
    • 默认情况下,如果注释处理发生且编译了隐式加载的源文件,编译器会发出警告。
    • 使用 -implicit 选项可以抑制该警告。

搜索类型

在编译 Java 源文件时,编译器需要查找和使用各种类型的信息,以下是对类型搜索过程的总结:

类型信息需求

  • 编译器需要了解源文件中使用、扩展或实现的每个类或接口,包括通过继承引入但未在源文件中直接提及的类型。

搜索过程

  • 编译器首先在引导类和扩展类中搜索类文件。
  • 然后编译器在用户类路径中搜索类文件,用户类路径默认为当前目录,可以通过设置 CLASSPATH 环境变量或使用 -classpath 选项来定义。
  • 如果设置了 -sourcepath 选项,编译器会在指定的路径中搜索源文件;否则,编译器会在用户类路径中同时搜索类文件和源文件。

引导和扩展类路径

  • 可以使用 -bootclasspath 和 -extdirs 选项来指定不同的引导或扩展类路径。

搜索结果

  • 类型搜索可能找到类文件、源文件或两者都有。
  • 使用 -Xprefer 选项可以指定编译器在找到两者时使用哪个文件(newer 或 source),默认为 newer。

源文件处理

  • 如果找到了源文件,编译器会读取它以获取所需信息,并默认编译该源文件。
  • -implicit 选项可以用来指定是否为找到的源文件生成类文件,默认情况下不会生成。

注释处理和警告

  • 编译器可能在注释处理完成后才意识到某些类型信息的需求。
  • 如果在源文件中找到类型信息且未指定 -implicit 选项,编译器会发出警告,指出该文件正在编译但未受注释处理。
  • 要禁用警告,可以在命令行上显式指定文件或使用 -implicit 选项。

编程接口

Java 编译器 javac 提供了编程接口,允许开发者以编程方式调用编译器,而不是通过命令行。

新 Java 编译器 API (javax.tools)

  • 支持:javac 命令支持由 javax.tools 包中的类和接口定义的新 Java 编译器 API。
  • 示例:以下是如何使用新 API 进行编译的示例:
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
// 这个示例将诊断信息写入标准输出流,并返回与命令行调用 `javac` 时相同的退出代码。
  • 功能:可以通过 javax.tools.JavaCompiler 接口中的其他方法来处理诊断信息、控制文件的读写位置等。

旧接口 (com.sun.tools.javac.Main)

  • 向后兼容:保留此 API 仅用于向后兼容。推荐新代码使用 javax.tools 中的新 Java 编译器 API。
  • 方法:com.sun.tools.javac.Main 类提供了两种静态方法来从程序中调用编译器:
    • public static int compile(String[] args);
    • public static int compile(String[] args, PrintWriter out);
  • 参数:
    • args:表示传递给编译器的命令行参数。
    • out:指定编译器诊断输出的位置。
  • 返回值:返回值等同于命令行调用 javac 的退出值。
  • 内部类和方法:以 com.sun.tools.javac 开头的包(及其子包)中的其他类和方法是内部的,可能会随时更改,不应在应用程序代码中使用。
更新时间: 2025/10/25 12:23