编译Foo.java:javac Foo.java
运行程序: java Foo
为什么编译器需要.java后缀但解释器不需要.class后缀?
正如其他几个答案所解释的那样,Java编译器将文件名作为参数,而解释器则采用类名.因此,您将.java扩展名赋予编译器,因为它是文件名的一部分,但您不会将其提供给解释器,因为它不是类名的一部分.
但是,你可能想知道,为什么他们不只是设计不同的Java解释器,以便它需要一个文件名?答案是,类并不总是从.class文件加载.有时它们来自JAR档案,有时它们来自互联网,有时它们是由程序实时构建的,依此类推.类可以来自任何可以提供定义它所需的二进制数据的源.也许同一个类可能有不同来源的不同实现,例如程序可能会尝试从URL加载某个类的最新版本,但如果失败则会回退到本地文件.Java的设计者认为,当您尝试运行程序时,您不必担心必须跟踪定义您正在运行的类的源.你只需要提供完全限定的类名,让Java(或者更确切地说,它的ClassLoaders)努力找到它.
Java编译器将文件名作为输入,因此使用Foo.java.
Java解释器获取完全限定的类名,并在类的路径和当前目录中搜索.如果您使用java Foo.class,它将在包"Foo"中搜索名为"class"的类,如果该类在默认包中,则返回NoClassDefFoundError,正如我从您的示例中所理解的