javac和java的-classpath选项

3
我对 -classpath 选项在编译和运行 java 程序中的作用感到困惑。请帮助我理解。
7个回答

5
因为它们是两个不同的操作,不一定是相同的路径。
运行时依赖关系通常比编译时依赖关系更广泛。例如,许多程序将编码到接口,这将限制编译时依赖关系只有这些接口。在运行时,虚拟机必须能够解析这些接口的实现,这些实现在加载运行时之前不需要。

2

这段话的意思是,无论是编译还是运行Java程序,都需要告诉javac和java在哪里找到所需的依赖项。


好的,但为什么要重复指定相同的东西?一次在编译期间,一次在运行期间? - gameover
这是一个“已知”的位置,Java将在其中查找不属于Java核心的类和JAR包。 - cjstehno
1
从严格意义上来说,你并没有做两次,而是进行了两个不同的操作。 - cjstehno
2
编译器需要知道这一点,以确保对象和方法调用是有效的。运行时需要它来实际使用这些对象和方法。 - Powerlord

2

代码被编译两次的原因是,你编译代码的环境可能与运行代码的环境不同。


2

Java在运行时加载类。例如,你可以编写一个方法来强制加载X类,先编译它,再编写X类并编译它们一起运行。此外,通常使用完全指定的名称引用类,但可以在同一程序中运行不同版本的该类(例如,库的不同版本)。因此,需要告诉Java可能找到需要加载的类的位置。

至于编译,为了确保类型安全,必须向Java编译器至少提供所引用和调用的接口或基类,以便编译器至少可以确保调用是合法的。出于这个原因,必须告诉编译器在哪里找到包含这些接口和基类的jar文件。

以下是一个例子。假设您想在核心Java程序中使用JMS(消息框架)。在编译时,您需要至少告诉javac在哪里找到JMS接口。在运行时,您需要提供这些接口,但还需要提供实际实现(例如ActiveMQ)的JAR。


1

在C++中,我相信链接是在编译时发生的,以创建可执行文件(我不是C++程序员,所以对此不确定)。

在Java中,链接器步骤发生在运行时(请参阅JVM规范,“Loading, Linking and Initalizing”)。从您的问题中可以看出,您理解为什么需要在编译时指定类路径(因为您可能会在代码中引用第三方JAR中的类),因此我将解释当您的程序正在运行时,这些类直到被引用才会加载到JVM中。此时,JVM需要知道在哪里找到它们的表示。


0
编译器必须知道在哪里查找以满足编译时依赖关系。 虚拟机必须知道在哪里查找以满足运行时依赖关系。

0

在编译时,您需要告诉javac在哪里找到第三方和用户定义的类。在运行时,您还需要告诉java在哪里找到第三方和用户定义的类。在这两种情况下,改变类路径的一种方法是使用JDK工具的-classpath选项。有关更多详细信息,请查看设置类路径技术说明。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接