Compiling Java *.class Files with javac – 用javac编译Java *.class文件

最后修改: 2018年 2月 4日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

This tutorial will introduce the javac tool and describes how to use it to compile Java source files into class files.

本教程将介绍javac工具,并说明如何使用它将Java源文件编译成类文件。

We’ll get started with a short description of the javac command, then examine the tool in more depth by looking at its various options.

我们将从javac命令的简短描述开始,然后通过查看它的各种选项来更深入地检查这个工具。

2. The javac Command

2、javac命令

We can specify options and source files when executing the javac tool:

我们可以在执行javac工具时指定选项和源文件。

javac [options] [source-files]

Where [options] denotes the options controlling operations of the tool, and [source-files] indicates one or more source files to be compiled.

其中[options]表示控制工具操作的选项,[source-files]表示一个或多个要被编译的源文件。

All options are indeed entirely optional. Source files can be directly specified as arguments to the javac command or kept in a referenced argument file as described later. Notice that source files should be arranged in a directory hierarchy corresponding to the fully qualified names of the types they contain.

所有的选项实际上都是完全可选的。源文件可以直接指定为javac命令的参数,也可以保存在一个参考参数文件中,如后面所述。注意,源文件应该被安排在与它们所包含的类型的完全合格名称相对应的目录层次中

Options of javac are categorized into three groups: standard, cross-compilation, and extra. In this article, we’ll focus on the standard and extra options.

javac的选项被分为三组:标准、交叉编译和额外。在这篇文章中,我们将重点讨论标准和额外选项。

The cross-compilation options are used for the less common use case of compiling type definitions against a JVM implementation different from the compiler’s environment and won’t be addressed.

交叉编译选项用于不太常见的使用情况,即针对不同于编译器环境的JVM实现来编译类型定义,因此不会被讨论。

3. Type Definition

3.类型定义

Let’s start by introducing the class we’re going to use to demonstrate the javac options:

让我们首先介绍一下我们要用来演示javac选项的类。

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

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

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

The source code is placed in the file com/baeldung/javac/Data.java.

源代码放在文件com/baeldung/javac/Data.java中。

Note that we use *nix file separators in this article; on Windows machines, we must use the backslash (‘\’) instead of the forward slash (‘/’).

请注意,我们在本文中使用了*nix的文件分隔符;在Windows机器上,我们必须使用反斜杠(’\’)而不是正斜杠(’/’)。

4. Standard Options

4.标准选项

One of the most commonly used standard options of the javac command is -d, specifying the destination directory for generated class files. If a type isn’t part of the default package, a directory structure reflecting the package’s name is created to keep the class file of that type.

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

Let’s execute the following command in the directory containing the structure provided in the previous section:

让我们在包含上一节提供的结构的目录中执行以下命令。

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

The javac compiler will generate the class file javac-target/com/baeldung/javac/Data.class. Note that on some systems, javac doesn’t automatically create the target directory, which is javac-target in this case. Therefore, we may need to do so manually.

javac编译器将生成类文件javac-target/com/baeldung/javac/Data.class。请注意,在某些系统上,javac不会自动创建目标目录,也就是本例中的javac-target。因此,我们可能需要手动操作。

Here are a couple of other frequently used options:

下面是其他几个经常使用的选项。

  • -cp (or -classpath, –class-path) – specifies where types required to compile our source files can be found. If this option is missing and the CLASSPATH environment variable isn’t set, the current working directory is used instead (as was the case in the example above).
  • -p (or –module-path) – indicates the location of necessary application modules. This option is only applicable to Java 9 and above – please refer to this tutorial for a guide to the Java 9 module system.

If we want to know what’s going on during a compilation process, e.g. which classes are loaded and which are compiled, we can apply the -verbose option.

如果我们想知道在编译过程中发生了什么,例如,哪些类被加载,哪些被编译,我们可以应用-verbose选项。

The last standard option we’ll cover is the argument file. Instead of passing arguments directly to the javac tool, we can store them in argument files. The names of those files, prefixed with the ‘@ character, are then used as command arguments.

我们要介绍的最后一个标准选项是参数文件。我们可以将参数直接传递给javac工具,而不是将它们存储在参数文件中。这些文件的名字,前缀为’@字符,然后作为命令参数使用。

When the javac command encounters an argument starting with ‘@, it interprets the following characters as the path to a file and expands the file’s content into an argument list. Spaces and newline characters can be used to separate arguments included in such an argument file.

javac命令遇到一个以’@开头的参数时,它会将下面的字符解释为一个文件的路径,并将该文件的内容扩展为一个参数列表。空格和换行符可以用来分隔包含在这样一个参数文件中的参数。

Let’s assume we have two files, named options, and types, in the javac-args directory with the following content:

我们假设在javac-args目录下有两个文件,名为options,和types,内容如下。

The options file:

options文件。

-d javac-target
-verbose

The types file:

types文件。

com/baeldung/javac/Data.java

We can compile the Data type like before with detail messages printed on the console by executing this command:

我们可以像以前一样编译Data类型,并通过执行这个命令在控制台打印详细信息。

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

Rather than keeping arguments in separate files, we can also store them all in a single file.

与其将参数保存在不同的文件中,我们也可以将它们全部保存在一个文件中

Suppose there is a file named arguments in the javac-args directory:

假设在javac-args目录中有一个名为arguments的文件。

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

Let’s feed this file to javac to achieve the same result as with the two separate files before:

让我们把这个文件送入javac,以实现与之前两个独立文件相同的结果

javac @javac-args/arguments

Notice the options we’ve gone through in this section are the most common ones only. For a complete list of standard javac options, check out this reference.

请注意,我们在本节中所介绍的选项只是最常见的选项。对于标准javac选项的完整列表,请查看这个参考资料

5. Extra Options

5.额外的选择

Extra options of javac are non-standard options, which are specific to the current compiler implementation and may be changed in the future. As such, we won’t go over these options in detail.

javac的额外选项为非标准选项,是针对当前编译器实现的,将来可能会有所改变。因此,我们将不详细讨论这些选项。

However, there is an option that’s very useful and worth mentioning, -Xlint. For a full description of the other javac extra options, follow this link.

然而,有一个选项非常有用,值得一提,-Xlint。关于其他javac额外选项的完整描述,请遵循这个链接

The -Xlint option allows us to enable warnings during compilation. There are two ways to specify this option on the command line:

Xlint选项允许我们在编译过程中启用警告。有两种方法可以在命令行中指定这个选项。

  • -Xlint – triggers all recommended warnings
  • -Xlint:key[,key]* – enables specific warnings

Here are some of the handiest -Xlint keys:

这里有一些最方便的-Xlint键。

  • rawtypes – warns about the use of raw types
  • unchecked – warns about unchecked operations
  • static – warns about the access to a static member from an instance member
  • cast – warns about unnecessary casts
  • serial – warns about serializable classes not having a serialversionUID
  • fallthrough – warns about the falling through in a switch statement

Now, create a file named xlint-ops in the javac-args directory with the following content:

现在,在javac-args目录下创建一个名为xlint-ops的文件,内容如下。

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

When running this command:

运行此命令时。

javac @javac-args/xlint-ops

we should see the rawtypes and unchecked warnings:

我们应该看到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. Conclusion

6.结论

This tutorial walked through the javac tool, showing how to use options to manage the typical compilation process.

本教程浏览了javac工具,展示了如何使用选项来管理典型的编译过程。

In reality, we usually compile a program using an IDE or a build tool rather than directly relying on javac. However, a solid understanding of this tool will allow us to customize the compilation in advanced use cases.

在现实中,我们通常使用IDE或构建工具来编译程序,而不是直接依赖javac。然而,对这个工具的扎实了解将使我们能够在高级用例中自定义编译。

As always, the source code for this tutorial can be found over on GitHub.

一如既往,本教程的源代码可以在GitHub上找到