Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
-javac和java的类路径选项_Java_Classpath - Fatal编程技术网

-javac和java的类路径选项

-javac和java的类路径选项,java,classpath,Java,Classpath,我对-classpath选项在编译和运行java程序中扮演的角色感到困惑。请帮助我理解。在这两种情况下,它都简单地告诉javac和java在何处查找程序编译和运行所需的依赖项编译器必须知道在何处查找以满足编译时依赖项。 VM必须知道在哪里查找满足运行时依赖关系。在C++中, < P>我相信链接发生在编译时间周围,创建一个可执行文件(我不是C++程序员,所以我不确定)。 在Java中,链接器步骤发生在运行时(请参阅JVM规范“”)。从您的问题中,您似乎理解了为什么需要在编译时指定类路径(因为您可能

我对
-classpath
选项在编译和运行java程序中扮演的角色感到困惑。请帮助我理解。

在这两种情况下,它都简单地告诉javac和java在何处查找程序编译和运行所需的依赖项

编译器必须知道在何处查找以满足编译时依赖项。
VM必须知道在哪里查找满足运行时依赖关系。在C++中,

< P>我相信链接发生在编译时间周围,创建一个可执行文件(我不是C++程序员,所以我不确定)。
在Java中,链接器步骤发生在运行时(请参阅JVM规范“”)。从您的问题中,您似乎理解了为什么需要在编译时指定类路径(因为您可能会在代码中引用来自第三方JAR的类),因此我将解释一下,当您的程序正在运行时,这些类在被引用之前不会加载到JVM中。此时,JVM需要知道在哪里可以找到它们的表示。

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

因为它们是两个独立的操作,不一定是相同的路径


运行时依赖项通常比编译时依赖项更广泛。例如,许多程序将编码到接口,这将编译时依赖关系限制到这些接口。在运行时,VM必须能够解析这些接口的实现,这些接口在运行时加载之前是不需要的。

之所以要执行两次,是因为编译代码的环境可能与运行代码的环境不同。

Java在运行时加载类。例如,您可以编写一个方法,强制加载类X,编译它,编写类X,编译它,然后将它们一起运行。此外,您通常使用完全指定的名称引用类,但可以使用该类的不同版本(例如,库的不同版本)运行相同的程序。因此,您需要告诉Java在哪里可以找到它需要加载的类

至于编译,为了确保类型安全,您必须至少向Java编译器提供您正在引用和调用的接口或基类,以便编译器至少能够确保调用是合法的。因此,你必须告诉它在哪里可以找到装有它们的罐子


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

好的,但是为什么要两次指定相同的内容呢?一次在编译过程中,一次在运行过程中?这是一个“已知”的地方,java将在这里查找不属于java核心的类和JAR。实际上,您并没有做两次,本质上,它们是两个独立的操作。编译器需要知道这一点,以确保对象和方法调用有效。运行时需要它实际使用所述对象和方法。