猿问

“java”命令可以编译 Java 程序吗?

互联网上的大多数网站都说:


“使用javac命令编译.java文件。然后使用java命令运行它”


但是今天我尝试在没有的情况下运行一个java程序,javac并且得到了一个奇怪的结果。


以下是名为 的文件的内容hello.java:


public class Myclass {

 public static void main(String[] args){

    System.out.println("hello world");

  }

}

然后我跑了:


$ javac hello.java

这给了我这个错误:


hello.java:1: error: class Myclass is public, should be declared in a file named Myclass.java

public class Myclass {

       ^

1 error

但是当我在没有javac命令的情况下运行它时,它执行时没有任何错误。


$ java hello.java

hello world

该java命令是否也编译程序?如果是的话,为什么我们需要这个javac命令?


我的java版本是:


openjdk version "12.0.2" 2019-07-16

OpenJDK Runtime Environment (build 12.0.2+10)

OpenJDK 64-Bit Server VM (build 12.0.2+10, mixed mode)


神不在的星期二
浏览 195回答 4
4回答

aluckdog

在 Java 11 之前,要运行代码,您必须首先编译它,然后才能运行它。这是一个例子:javac test.javajava test从 Java 11 开始,您仍然可以执行javac+操作java,或者可以java单独运行来编译并自动运行您的代码。请注意,不会.class生成任何文件。这是一个例子:java test.java如果运行java -help,您将看到各种允许的用法。这是我的机器上的样子。最后一个是您遇到的情况:java [options] <sourcefile> [args]它将“执行单个源文件程序”。$ java -helpUsage: 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 的早期阶段以及编写小型实用程序”变得更容易,而不改变任何其他现有用途。

函数式编程

如果您运行的是 Java 11,则有一项新功能允许执行单个源文件。单源编译器在类名与文件名方面更加混杂,因此您可以运行但无法成功编译。如果您使用的是以前版本的 Java,则当前的 hello.java 不会编译,因为编译错误,特别是类名周围的错误。因此,调用 java hello.java 绝对不可能编译您的代码,因为它无法编译。看起来很可能您在执行 java 命令时正在运行一些先前编译的代码。

慕斯709654

要回答出现此错误的原因,文件的类名必须与文件的basename.您有两种选择让此代码适用于传统的javac;java顺序:将类重命名为public class Hello或重命名hello.java为myclass.java.Java 11 的解释java器没有强加此要求。包含的类main可以具有任何名称,只要它是文件中的第一个类即可。

森林海

是的,但不是你想的那样。当您使用该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,它实际上可能没有时间运行任何已编译的本机代码)
随时随地看视频慕课网APP

相关分类

Java
我要回答