4 回答
TA贡献1847条经验 获得超7个赞
在 Java 11 之前,要运行代码,您必须首先编译它,然后才能运行它。这是一个例子:
javac test.java
java test
从 Java 11 开始,您仍然可以执行javac+操作java,或者可以java单独运行来编译并自动运行您的代码。请注意,不会.class生成任何文件。这是一个例子:
java test.java
如果运行java -help,您将看到各种允许的用法。这是我的机器上的样子。最后一个是您遇到的情况:java [options] <sourcefile> [args]它将“执行单个源文件程序”。
$ java -help
Usage: java [options] <mainclass> [args...]
(to execute a class)
or java [options] -jar <jarfile> [args...]
(to execute a jar file)
or java [options] -m <module>[/<mainclass>] [args...]
java [options] --module <module>[/<mainclass>] [args...]
(to execute the main class in a module)
or java [options] <sourcefile> [args]
(to execute a single source-file program)
我们需要javac创建.class文件,以便可以像今天一样创建、测试、分发、运行、共享代码等。JEP 330的动机是让“学习 Java 的早期阶段以及编写小型实用程序”变得更容易,而不改变任何其他现有用途。
TA贡献1807条经验 获得超9个赞
如果您运行的是 Java 11,则有一项新功能允许执行单个源文件。单源编译器在类名与文件名方面更加混杂,因此您可以运行但无法成功编译。
如果您使用的是以前版本的 Java,则当前的 hello.java 不会编译,因为编译错误,特别是类名周围的错误。因此,调用 java hello.java 绝对不可能编译您的代码,因为它无法编译。
看起来很可能您在执行 java 命令时正在运行一些先前编译的代码。
TA贡献1840条经验 获得超5个赞
要回答出现此错误的原因,文件的类名必须与文件的basename
.
您有两种选择让此代码适用于传统的javac
;java
顺序:
将类重命名为
public class Hello
或重命名
hello.java
为myclass.java
.
Java 11 的解释java
器没有强加此要求。包含的类main
可以具有任何名称,只要它是文件中的第一个类即可。
TA贡献2011条经验 获得超2个赞
是的,但不是你想的那样。
当您使用该javac
命令将 .java 文件编译为 .class 文件时,输出称为字节码。字节码是基于 Java 虚拟机规范的理论 CPU 的机器代码(本机指令)。
此虚拟 CPU 规范是编写规范时常见的 CPU 类型的平均值。因此,它接近许多不同类型的 CPU,从而更容易在多种 CPU 类型上运行相同的 Java .class 文件。
当 Java 第一次启动时,该java
命令将读取 .class 文件并一次解释一个字节码指令,然后将它们映射到实际运行的 CPU 的等效本机指令。这有效但不是特别快。为了改进这一点,Java 运行时中添加了即时 (JIT) 编译。
通过 JIT,该java
命令获取字节码并将其再次编译为其运行的 CPU 的本机指令。现代 Java 运行时倾向于在后台进行 JIT 编译时开始解释字节码,并在准备就绪时切换到已编译的本机指令,并且还将分析正在运行的应用程序,然后使用不同的优化再次重新编译字节码,以获得最佳性能。
编辑(安抚反对者):
因此,在您的特定情况下(因为您运行的是比 v11 更新的 JRE),代码会(至少)编译两次
作为字节码的单个 .java 文件
通过 JIT 编译器解释字节码(尽管对于 helloWorld,它实际上可能没有时间运行任何已编译的本机代码)
添加回答
举报