javac 和 java 的 -classpath 选项
我对 -classpath
选项在 编译和运行 java 程序中所扮演的角色感到困惑。请帮助我理解。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我对 -classpath
选项在 编译和运行 java 程序中所扮演的角色感到困惑。请帮助我理解。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(7)
因为它们是两个独立的操作,不一定是相同的路径。
运行时依赖性通常比编译时依赖性更广泛。例如,许多程序将针对接口进行编码,这限制了对这些接口的编译时依赖性。在运行时,VM 必须能够解析这些接口的实现,而在运行时加载这些接口之前不需要这些实现。
Because they are two separate operations and not necessarily the same paths.
The runtime dependencies are often more extensive than the compile time dependencies. For example, many programs will code to interfaces, which limits the compile time dependencies to those interfaces. At runtime, the VM must be able to resolve the implementations of those interfaces, which are not required until they are loaded at runtime.
它只是在这两种情况下告诉 javac 和 java 在哪里找到程序编译和运行所需的依赖项
it simply in both cases tells javac and java where to find dependencies required for your program to both compile and run
执行两次的原因是编译代码的环境可能与运行代码的环境不同。
The reason it is done twice is that the environment you compile the code in may not be the same environment you run the code in.
Java 在运行时加载类。例如,您可以编写一个方法来强制加载类 X,编译它,编写类 X,编译它,然后一起运行它们。此外,您通常通过完全指定的名称来引用类,但可以使用该类的不同版本(例如,库的不同版本)运行相同的程序。因此,您需要告诉 Java 在哪里可以找到它需要加载的类。
至于编译,为了保证类型安全,你必须至少向Java编译器提供你所引用和调用的接口或基类,这样编译器至少可以保证:该调用将是合法的。因此,您必须告诉它在哪里可以找到包含它们的罐子。
这是一个例子。假设您想在核心 Java 程序中使用 JMS(消息传递框架)。在编译时,您至少需要告诉 javac 在哪里可以找到 JMS 接口。在运行时,您需要提供这些接口,但您还需要提供具有实际实现的JAR(例如ActiveMQ)。
Java loads classes at runtime. For example, you could write a method that forces loading of class X, compile it, write class X, compile it, and then run them together. In addition, you typically refer to classes by a fully specified name, but could run the same program with different versions of that class (e.g., a different version of the library). Thus, you need to tell Java where it could potentially find the classes that it needs to load.
As for compilation, to ensure type safety, you have to provide the Java compiler at least with the interfaces or base classes that you are referring to and making calls on, so that the compiler can at least ensure that the call would be legal. For that reason, you have to tell it where to find the jars containing them.
Here is an example. Let's say you want to use JMS (a messaging framework) in a core Java program. At compile time, you need to at least tell javac where to find the JMS interfaces. At runtime, you need to provide these interfaces, but you also need to provide the JAR with the actual implementation (e.g., ActiveMQ).
在 C++ 中,我相信链接发生在编译时,以创建可执行文件(我不是 C++ 程序员,所以我对此不确定)。
在 Java 中,链接器步骤发生在运行时(请参阅 JVM 规范,“加载、链接和初始化")。从你的问题来看,你似乎明白为什么需要在编译时指定类路径(因为你可能会在代码中引用第三方 JAR 中的类),所以我只会解释一下,当你的程序运行时,这些类是在引用它们之前,它们不会加载到 JVM 中。此时,JVM 需要知道在哪里可以找到它们的表示形式。
In C++ I believe it is the case that linking happens around compile-time, to create an executable (I am not a C++ programmer so I'm not sure about that).
In Java, the linker step happens at runtime (see the JVM spec, "Loading, Linking and Initalizing"). From your question it sounds like you understand why the classpath needs to be specified at compile time (because you might reference classes from third-party JARs in your code), so I will just explain that when your program is being run, those classes are not loaded into the JVM until they are referenced. At this point, the JVM needs to know where to find their representation.
编译器必须知道在哪里寻找以满足编译时依赖性。
虚拟机必须知道在哪里寻找以满足运行时依赖性。
The compiler has to know where to look to satisfy compile-time dependencies.
The VM has to know where to look to satisfy runtime dependencies.
在编译时,您需要告诉
javac
在哪里可以找到第三方和用户定义的类。在运行时,您还需要告诉java
在哪里可以找到第三方和用户定义的类。在这两种情况下,更改类路径的一种方法是使用 JDK 工具的 -classpath 选项。查看设置类路径技术说明了解更多详情。At compile time, you need to tell
javac
where to find third-party and user-defined classes. At runtime, you also need to telljava
where to find third-party and user-defined classes. In both cases, one way to change the class path is to use the JDK Tools' -classpath option. Checkout the Setting the Class Path technical note for more details.