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,它實際上可能沒有時間運行任何已編譯的本機代碼)
添加回答
舉報