管理 Java 类路径(UNIX 和 Mac OS X)-2
- UID
- 1066743
|
管理 Java 类路径(UNIX 和 Mac OS X)-2
源路径源路径 就是 Java 在其中寻找源文件的那个目录。具体到本例,就是 src 目录。该目录必须包含源文件的层次结构,这些源文件可以被放到它们自己的目录中。因此它不是 com 目录也不是 src/com/elharo/math 目录。
很多项目都使用不止一个类和包。它们通过导入语句和完整的包限定类名连接起来。例如,假设您在 com.elharo.gui 包里面创建一个新的 MainFrame 类 如清单 1 所示:
清单 1. 一个包中的类可以导入另一个包中的类1
2
3
4
5
6
7
8
9
10
11
12
| package com.elharo.gui;
import com.elharo.math.*;
public class MainFrame {
public static void main(String[] args) {
Fraction f = new Fraction();
// ...
}
}
|
该类使用的是与 MainFrame 类所在的包不同的包中的 com.elharo.math.Fraction类。源设置现在应该如图 3 所示(我将编译后的输出从之前的步骤中删除了。但这没有关系,因为我总是能重新编译它)。
图 3. 几个包的源结构现在来看一下试着像以前一样编译 MainFrame.java 会出现什么情况。
清单 2. 编译 MainFrame.java1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| $ javac -d bin src/com/elharo/gui/MainFrame.java
src/com/elharo/gui/MainFrame.java:3: package com.elharo.math does not exist
import com.elharo.math.*;
^
src/com/elharo/gui/MainFrame.java:7: cannot find symbol
symbol : class Fraction
location: class com.elharo.gui.MainFrame
private Fraction f = new Fraction();
^
src/com/elharo/gui/MainFrame.java:7: cannot find symbol
symbol : class Fraction
location: class com.elharo.gui.MainFrame
private Fraction f = new Fraction();
^
3 errors
|
出现清单 2 中的错误的原因是,虽然 javac 知道到何处可以找到 MainFrame.java,但它却并不知道到何处可以找到 Fraction.java(您可能觉得它应该具备足够的智能来识别匹配的层次结构,但事实并非如此)。为了给它提供一些线索,必须指定源路径。用源路径指定编译器应该到哪些目录查找源文件的层次结构。在清单 2 中,源路径是 src。所以我使用了 -sourcepath 选项,如下所示:
1
| $ javac -d bin -sourcepath src src/com/elharo/gui/MainFrame.java
|
现在再编译程序,就不会出现错误,并会产生如图 5 所示的输出。请注意 javac 也编译了文件 Fraction.java,Fraction.java 被当前编译的文件引用。
图 4. 多类输出在源路径中编译多个目录在源路径中可以有多个目录,使用冒号分隔各目录,但通常没有必要这么做。例如,若我想包括本地的 src 目录和用来存放另一个项目的源代码的 /Users/elharo/Projects/XOM/src 目录,我可以这样进行编译:
1
2
| $ javac -d bin -sourcepath src:/Users/elharo/Projects/XOM/src
src/com/elharo/gui/MainFrame.java
|
该命令并不编译在这两个层次结构中所找到的每个文件。它只编译由单个的 .java 文件直接或间接引用的文件,而此 .java 文件必须被编译。
更常见的情况是,为 .java 文件用一个单一的源目录,为类或放置了预编译的第三方库的 JAR 归档文件用多个目录。而这正是类路径的作用所在。
设置类路径在大中型项目中,每次都要对每个文件进行重编译会非常耗时。为减少这种编译负担,可以在不同的 bin 目录分别编译和存储相同项目的独立部分。这些目录被添加到类路径。
将类添加到类路径有几种方法可选。但您只能使用 -classpath 命令行开关。例如,假设我想从另一个之前已经编译到目录 /Users/elharo/classes 的工程导入文件,那么我会向命令行添加 -classpath/Users/elharo/classes,如下所示:
1
2
| $ javac -d bin -sourcepath src -classpath /Users/elharo/classes
src/com/elharo/gui/MainFrame.java
|
现在假设需要添加两个目录,/Users/elharo/project1/classes 和 /Users/elharo/project2/classes。那么我将包含它们并使用冒号将它们分隔开,如下所示:
1
2
3
| $ javac -d bin -sourcepath src
-classpath /Users/elharo/project1/classes:/Users/elharo/project2/classes
src/com/elharo/gui/MainFrame.java
|
顶级目录请注意这里所说的顶级目录是指所有包含包的层次结构的顶级目录,包括 com/elharo/foo/bar 或 nu/xom/util 的层次结构。具有匹配包名称(com、elharo、math 等)的目录绝不会直接包括在源路径或类路径中。
当然,您也可以使用自己喜欢的各种相对路径的格式。比如,如果 project1 和 project2 是当前工作目录的同级目录(即它们有相同的父目录),那么我会这样引用它们:
1
2
3
| $ javac -d bin -sourcepath src
-classpath ../project1/classes:../project2/classes
src/com/elharo/gui/MainFrame.java
|
到目前为止,我都一直假设程序完全独立并且没有使用任何单独的编译后的第三方库。如果需要使用第三方库,还必须将它们也添加到类路径。库通常是 JAR 文件的格式,比如 junit.jar 或 icu4j.jar。在本例中,需要向类路径添加的只是 JAR 文件本身,而不是包含 JAR 文件的目录(从实质上讲,JAR 文件可以充当包含编译后的 .class 文件的一种目录)。例如,如下命令会向类路径添加三项内容:/Users/elharo/classes 目录,当前工作目录里的 icu4j.jar 文件和 /Users/elharo/lib 下的 junit.jar 文件:
1
2
3
| $ javac -d bin -sourcepath src
-classpath /Users/elharo/classes:icu4j.jar:/Users/elharo/lib/junit.jar
src/com/elharo/gui/MainFrame.java
|
JAR 文件仅用于 .class 文件和其类路径,不用于 .java 文件及其源路径。 |
|
|
|
|
|