2011-12-28 87 views

回答

7

正如其他一些答案所解釋的那樣,Java編譯器將文件名作爲參數,而解釋器採用類名。因此,您將.java擴展名賦予編譯器,因爲它是文件名的一部分,但不會將它傳遞給解釋器,因爲它不是類名的一部分。

但是,您可能會想,爲什麼他們不只是設計不同的Java解釋器,以至於需要一個文件名呢?答案是類不總是從.class文件加載。有時它們來自JAR檔案,有時它們來自from the internet,有時它們是通過程序實時構建的,等等。一個類可以來自任何可以提供所需的二進制數據的來源to define it。也許同一個類可能具有不同來源的不同實現,例如程序可能會嘗試從URL加載某個類的最新版本,但如果失敗則會回退到本地文件。 Java的設計者認爲,當你試圖運行一個程序時,你不必擔心必須跟蹤定義你正在運行的類的源代碼。您只需提供完全合格的類名稱,然後讓Java(或更確切地說,它的ClassLoader)來完成查找它的努力工作。

+0

很好解釋。 – novice 2011-12-29 04:33:01

5

Java編譯器將一個文件名作爲輸入,因此是Foo.java。

Java解釋器獲取完全限定的類名並搜索類的類路徑和當前目錄。如果您使用java Foo.class,它會搜索包「Foo」中名爲「class」的類,並且如果該類處於默認包中,則返回NoClassDefFoundError,正如我從您的示例中瞭解的那樣

2

Foo.java is只是「Foo」的文件名是類名(不是文件名)。默認的ClassLoader將搜索當前工作目錄中的文件Foo.class並加載它。

0

每種語言都有語法和語義,它們將建立相似方之間的規則和理解。就像英語如何有文字,時態,動詞等一樣,以簡化說英語的兩方之間的溝通。 Java規範建立了語法和語義,編譯器只能理解java文件,解釋器只能理解.class文件。

1

添加到大衛Zaslavsky的解釋:

Java源代碼不一定是從.java文件不管。我們可以有一個編譯器,它從差異字符流中獲取源代碼,如API javax.tools.JavaCompiler中所述。

cmd行util javac恰好只與文件源一起工作,所以它需要文件路徑。

+0

一個公平點,但爲了解釋這個特定的設計決定,你必須回頭看看Java 1。0,其中'FileObject'抽象不存在,並且處理源代碼的唯一方法是將其放入一個文件中(或從頭編寫自己的編譯器)。相反,'ClassLoader'從一開始就一直存在。 – 2011-12-28 09:02:13