是';java';命令编译Java程序?
互联网上的大多数网站都说: “使用是';java';命令编译Java程序?,java,javac,Java,Javac,互联网上的大多数网站都说: “使用javac命令编译.java文件。然后使用java命令运行它” 但是今天我尝试运行一个没有javac的java程序,结果很奇怪 下面是名为hello.java的文件的内容: public class Myclass { public static void main(String[] args){ System.out.println("hello world"); } } 然后我跑: $ javac hello.java 这给了我一个错误:
javac
命令编译.java
文件。然后使用java
命令运行它”
但是今天我尝试运行一个没有javac
的java程序,结果很奇怪
下面是名为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
命令
my 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)
如果您运行的是Java 11,有一个新功能允许执行单个源文件。单源编译器在类名和文件名方面更加混乱,因此这就是您能够运行但无法成功编译的方式 如果您使用的是以前版本的Java,那么您当前的hello.Java不会编译,因为编译错误,特别是类名周围的错误。所以调用java hello.java绝对不可能编译代码,因为它不编译
在执行java命令时,您很可能正在运行一些以前编译过的代码 在Java 11之前,要运行代码,必须先编译代码,然后才能运行它。下面是一个例子:
javac test.java
java test
java test.java
自Java11以来,您仍然可以执行javac
+Java
,或者您可以自行运行Java
来编译和自动运行代码。请注意,不会生成.class
文件。下面是一个例子:
javac test.java
java test
java test.java
如果运行java-help
,您将看到各种允许的用法。这是我的机器上的样子。最后一个是您遇到的:java[options][args]
,它将“执行单个源文件程序”
$java-帮助
用法:java[options][args…]
(执行一个类)
或java[options]-jar[args…]
(执行jar文件)
或java[options]-m[/][args…]
java[选项]--模块[/][args…]
(在模块中执行主类)
或java[options][args]
(执行单个源文件程序)
更新:
正如@BillK所指出的,OP还提出了以下问题:
为什么我们需要javac命令
我们需要
javac
的原因是创建.class
文件,这样代码就可以像今天一样被创建、测试、分发、运行、共享等等。其动机是使“学习Java的早期阶段以及编写小型实用程序时”变得更容易,而不改变任何其他现有用途。是的,但不是你可能的意思
当您使用javac
命令将.java文件编译成.class文件时,输出是一种称为字节码的东西。字节码是基于Java虚拟机规范的理论CPU的机器代码(本机指令)
这个虚拟CPU规范是在编写规范时常见的CPU类型的平均值。因此,它接近于许多不同类型的CPU,使得在多个CPU类型上运行相同的Java.class文件变得更容易
当Java第一次启动时,Java
命令将读取.class文件,一次一个地解释字节码指令,然后将它们映射到它实际运行的CPU的等效本机指令。这很有效,但不是特别快。为了改进这一点,将JIT编译添加到Java运行时中
使用JIT时,java
命令获取字节码,并将其再次编译为运行该字节码的CPU的本机指令。现代Java运行时倾向于在后台JIT编译时开始解释字节码,并在准备就绪时切换到编译的本机指令,还将评测正在运行的应用程序,然后以不同的优化重新编译字节码,以获得最佳性能
编辑(以安抚落选的选民):
因此,在您的特定情况下(当您运行比v11更新的JRE时),代码被编译(至少)两次
要回答出现此错误的原因,文件的类名必须与文件的
basename
匹配
对于传统的javac
,有两个选项可以让此代码工作<代码>java顺序:
公共类Hello
或hello.java
重命名为myclass.java
java 11的
java
解释器不强制执行此要求。包含main
的类可以有任何名称,只要它是文件中的第一个类。这主要是为了简化初学者的学习过程,并允许使用shebang()编写“java脚本”。您使用的是哪个版本?我认为他们在Java9中引入了Java控制台,这可能就是您所经历的。您需要将类名与其文件名匹配—这是Java标准。只需将文件名更改为Myclass.java
,然后从命令行像这样编译javacmyclass.java
,然后像这样运行javamyclass
。是的,javac
仍然用于编译,如果您不想部署源代码,或者您有多个文件(对于源文件选项,java
:仅用于启动单个源文件程序。)@Matthieu“java-version”的输出为:openjdk version“12.0.2”2019-07-16 openjdk运行时环境(build 12.0)。