为什么我们不在命令filename.class
之后给出文件java
,而不仅仅是filename
?
假设我们要编译test.java
程序,那么我们运行javac test.java
. 没关系!
之后它将生成test.class
文件,但要运行我们运行的程序java test
而不是java test.class
. 这是什么原因?
为什么我们不在命令filename.class
之后给出文件java
,而不仅仅是filename
?
假设我们要编译test.java
程序,那么我们运行javac test.java
. 没关系!
之后它将生成test.class
文件,但要运行我们运行的程序java test
而不是java test.class
. 这是什么原因?
因为您没有描述要运行的文件。您正在告诉 Java 哪个类包含主要方法 - 并且该类的名称是 (在您的情况下) filename
,而不是filename.class
.
字节码几乎总是包含在文件系统上的文件中这一事实是一个实现细节。传递给java
命令的类路径告诉它在哪里寻找类,然后主类参数告诉它使用哪个类。
(对于 不同javac
,因为这个程序专门获取源文件并将它们编译成字节码。)
您也不会将文件名传递给 java 命令。你传递给它一个完全限定的类名。类似的东西com.yourcompany.yourapp.Main
。然后,Java 通过查看类路径中的所有目录和 jar 文件来找到这个类名的 .class 文件。
这是一个实现细节。Java 类加载器系统可以通过自定义代码进行扩展,以使其行为不同。例如,一些公司已经编写了加密类加载器,它们能够即时解密和加载加密的类文件。您可以假设创建一个类似的系统,将一堆类捆绑在一起,形成类似于 .NET 程序集的东西,而不是 Jar 文件(实际上只是一个 zip 文件)。
当你执行“ java test.class
”
你得到要么
无法找到或加载主类 test.class
或者
线程“main”中的异常 java.lang.NoClassDefFoundError: test/class
这是因为“ java
”中的“ java test.class
”是jvm
。class
它在名为“ ”而不是“ ”的类中查找主要方法test
。“ java test.class
”中的点具有重要意义。那么如何jvm
看待“ java test.class
”,在一个名为“ test
”的包中,它会寻找一个名为“ class
”的java类。
*test.class*
*test* - package name
*class* - java filename
希望这可以帮助 !!
只是总结一切到细节,
当一个人
java filename.java
他/她实际上运行 java 编译器并将代码转换为 JVM 可以理解的指令。
现在当一个人跑
javac main_file
他/她调用 JVM 来运行其 main 方法在类main_file中找到的整个项目
这个main_file实际上是类的完全限定名称,即如果我有一个项目 ProjectX 并且这个主类在包src.java.hello.main中,
你应该运行命令
java src.java.hello.main.main_file
因此,这.
实际上是 JVM 端的保留内容,我们不能将.class
其作为java命令参数的一部分。
Javac 编译器创建一个名为 Xyz.class(这里 Xyz 是 FileName)的文件,其中包含程序的字节版本 Java 字节码只不过是您的程序的中间表示,其中包含 Java 解释器将执行的指令。
因此,javac 的输出不是可以直接执行的代码
简而言之,javac关键字用于编译Java程序如果我们使用.class和javac(已经编译的文件.class文件)那么如何编译已经编译的文件
所以有效的语法是:Javac Xyz.java(编译 Java 程序)java Xyz(运行 Java 程序)