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