1. 概述
在这个教程中,我们将学习如何通过命令行界面与Java编译器交互。
在开始之前,我们需要确保已经安装了Java,并在机器上配置了JAVA_HOME环境变量。
2. 单个Java源代码文件的编译
Java提供了一个简单的工具——javac,用于编译Java源代码文件。我们先从编译一个简单的类,Car.java
开始:
public class Car {
private String make;
private String model;
// standard setters and getters
}
我们可以在该文件所在的目录中使用单条命令进行编译:
javac Car.java
如果一切顺利,没有错误,将不会有任何输出。编译器会在当前工作目录下生成包含字节码的Car.class
文件。
3. 多个源代码文件的编译
通常,我们的程序会使用多个类文件。现在让我们看看如何编译一个包含多个类的简单程序。
首先,添加两个新类型:Owner.java
和 History.java
:
public class Car {
private String make;
private String model;
private Owner owner;
private History history;
}
public class Owner {
private String name;
}
public class History {
private String details;
}
现在,我们需要运行以下命令进行编译:
javac Owner.java Car.java History.java
需要注意的是,由于Car
类使用的类都在同一目录下,指定它们实际上是可选的。 我们仍然可以直接编译Car.java
。
4. Java编译器的基本选项
到目前为止,我们只是通过参数传递类名的方式使用javac
命令,而没有额外的选项。但也可以进行自定义。我们可以告诉Java编译器查找我们的库类的位置、代码所在的根路径,以及最终结果的生成位置。
让我们更深入地了解其中一些选项。
- --cp 或 --classpath
- --sourcepath
- --d (目录)
4.1. 什么是--cp*或--classpath选项?*
使用类路径,我们可以定义一组依赖于编译时的目录或文件,如*.jar
、*.zip
。或者,可以通过设置CLASSPATH
环境变量来指定。
需要注意的是,类路径选项的优先级高于环境变量。
如果没有指定,类路径默认为当前目录。当需要指定多个目录时,对于大多数操作系统(除Windows外),路径分隔符是*:*
,而在Windows上是*;*
。
4.2. 什么是*--sourcepath*选项?
这个选项使得我们可以指定所有需要编译的源代码的顶级目录。
如果不指定,编译器会扫描类路径寻找源代码。
4.3. 什么是*--d*选项?
当我们希望所有编译结果都放在一个地方,且与源代码分开时,使用此选项。我们需要记住,要指定的路径必须事先存在。
在编译过程中,这个路径被用作根目录,根据类的包结构自动创建子目录。如果没有指定此选项,每个*.class
文件将被写入其对应*.java
源文件旁边。
5. 使用外部库进行编译
除了我们创建的类之外,我们的程序还需要使用外部库。现在让我们看一个更复杂的例子:
libs/
├─ guava-31.1-jre.jar
model/
├─ Car.java
├─ History.java
├─ Owner.java
service/
├─ CarService.java
target/
在这里,我们按照包组织了类。此外,我们添加了target
和libs
目录,分别用于存放编译结果和库。
假设我们要使用Guava库提供的ImmutableSet
类。我们下载并将其放在libs
文件夹中。然后,在service
包中,我们在CarService.java
中引入一个使用外部库的新类:
package service;
import model.Car;
import java.util.Set;
import com.google.common.collect.ImmutableSet;
public class CarService {
public Set<Car> getCars() {
Car car1 = new Car();
Car car2 = new Car();
ImmutableSet<Car> cars = ImmutableSet.<Car>builder()
.add(car1)
.add(car2)
.build();
return cars;
}
}
现在,是时候编译我们的项目了:
javac -classpath libs/*:. -d target -sourcepath . service/CarService.java model/*.java
我们在类路径中包含了libs
文件夹,使用-\-cp
。
libs/
├─ guava-31.1-jre.jar
model/
├─ Car.java
├─ History.java
├─ Owner.java
service/
├─ CarService.java
target/
├─ model/
│ ├─ Car.class
│ ├─ History.class
│ ├─ Owner.class
├─ service/
│ ├─ CarService.class
如我们所见,javac
成功解析了外部的ImmutableSet
类,并将编译后的类放在target
文件夹中。
6. 总结
在这篇文章中,我们学习了如何编译多个源代码文件,即使它们依赖于外部库。
此外,我们还快速了解了一些在复杂编译任务中可以利用的关键选项。