2011-12-28 88 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