編譯Foo.java: javac的Foo.java爲什麼編譯器需要.java後綴但解釋器不需要.class後綴?
要運行的程序:的Java富
爲什麼編譯器需要.java
後綴,但解釋並不需要.class
後綴?
編譯Foo.java: javac的Foo.java爲什麼編譯器需要.java後綴但解釋器不需要.class後綴?
要運行的程序:的Java富
爲什麼編譯器需要.java
後綴,但解釋並不需要.class
後綴?
正如其他一些答案所解釋的那樣,Java編譯器將文件名作爲參數,而解釋器採用類名。因此,您將.java
擴展名賦予編譯器,因爲它是文件名的一部分,但不會將它傳遞給解釋器,因爲它不是類名的一部分。
但是,您可能會想,爲什麼他們不只是設計不同的Java解釋器,以至於需要一個文件名呢?答案是類不總是從.class
文件加載。有時它們來自JAR檔案,有時它們來自from the internet,有時它們是通過程序實時構建的,等等。一個類可以來自任何可以提供所需的二進制數據的來源to define it。也許同一個類可能具有不同來源的不同實現,例如程序可能會嘗試從URL加載某個類的最新版本,但如果失敗則會回退到本地文件。 Java的設計者認爲,當你試圖運行一個程序時,你不必擔心必須跟蹤定義你正在運行的類的源代碼。您只需提供完全合格的類名稱,然後讓Java(或更確切地說,它的ClassLoader
)來完成查找它的努力工作。
很好解釋。 – novice 2011-12-29 04:33:01
Java編譯器將一個文件名作爲輸入,因此是Foo.java。
Java解釋器獲取完全限定的類名並搜索類的類路徑和當前目錄。如果您使用java Foo.class,它會搜索包「Foo」中名爲「class」的類,並且如果該類處於默認包中,則返回NoClassDefFoundError,正如我從您的示例中瞭解的那樣
Foo.java is只是「Foo」的文件名是類名(不是文件名)。默認的ClassLoader將搜索當前工作目錄中的文件Foo.class並加載它。
每種語言都有語法和語義,它們將建立相似方之間的規則和理解。就像英語如何有文字,時態,動詞等一樣,以簡化說英語的兩方之間的溝通。 Java規範建立了語法和語義,編譯器只能理解java文件,解釋器只能理解.class文件。
添加到大衛Zaslavsky的解釋:
Java源代碼不一定是從.java
文件不管。我們可以有一個編譯器,它從差異字符流中獲取源代碼,如API javax.tools.JavaCompiler
中所述。
cmd行util javac
恰好只與文件源一起工作,所以它需要文件路徑。
一個公平點,但爲了解釋這個特定的設計決定,你必須回頭看看Java 1。0,其中'FileObject'抽象不存在,並且處理源代碼的唯一方法是將其放入一個文件中(或從頭編寫自己的編譯器)。相反,'ClassLoader'從一開始就一直存在。 – 2011-12-28 09:02:13
這不是文件名。請注意,它是'javac pkg/Foo.java',但是'java pkg.Foo'。小蘋果像往常一樣精神抖something。 – 2011-12-28 02:10:19