为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

神不在的星期二 2023-08-23 17:10:03
互联网上的大多数网站都说:“使用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.javapublic class Myclass {       ^1 error但是当我在没有javac命令的情况下运行它时,它执行时没有任何错误。$ java hello.javahello world该java命令是否也编译程序?如果是的话,为什么我们需要这个javac命令?我的java版本是:openjdk version "12.0.2" 2019-07-16OpenJDK Runtime Environment (build 12.0.2+10)OpenJDK 64-Bit Server VM (build 12.0.2+10, mixed mode)
查看完整描述

4 回答

?
aluckdog

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 的早期阶段以及编写小型实用程序”变得更容易,而不改变任何其他现有用途。


查看完整回答
反对 回复 2023-08-23
?
函数式编程

TA贡献1807条经验 获得超9个赞

如果您运行的是 Java 11,则有一项新功能允许执行单个源文件。单源编译器在类名与文件名方面更加混杂,因此您可以运行但无法成功编译。

如果您使用的是以前版本的 Java,则当前的 hello.java 不会编译,因为编译错误,特别是类名周围的错误。因此,调用 java hello.java 绝对不可能编译您的代码,因为它无法编译。

看起来很可能您在执行 java 命令时正在运行一些先前编译的代码。


查看完整回答
反对 回复 2023-08-23
?
慕斯709654

TA贡献1840条经验 获得超5个赞

要回答出现此错误的原因,文件的类名必须与文件的basename.

您有两种选择让此代码适用于传统的javacjava顺序:

  1. 将类重命名为public class Hello

  2. 重命名hello.javamyclass.java.

Java 11 的解释java器没有强加此要求。包含的类main可以具有任何名称,只要它是文件中的第一个类即可。


查看完整回答
反对 回复 2023-08-23
?
森林海

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),代码会(至少)编译两次

  1. 作为字节码的单个 .java 文件

  2. 通过 JIT 编译器解释字节码(尽管对于 helloWorld,它实际上可能没有时间运行任何已编译的本机代码)


查看完整回答
反对 回复 2023-08-23
  • 4 回答
  • 0 关注
  • 141 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信