[英]Why compiler needs .java suffix but interpreter doesn't need .class suffix?
编译Foo.java:javac Foo.java
运行程序: java Foo
为什么编译器需要.java
后缀,但解释器不需要.class
后缀?
正如其他几个答案所解释的那样,Java编译器采用文件名作为参数,而解释器采用类名。 因此,您将.java
扩展名赋予编译器,因为它是文件名的一部分,但不将其提供给解释器,因为它不是类名的一部分。
但是,然后,您可能想知道,为什么他们不只是以不同的方式设计Java解释器,以便采用文件名? 答案是,并非总是从.class
文件中加载.class
。 有时它们来自JAR档案,有时它们来自互联网 ,有时它们是由程序动态构建的,依此类推。 一个类可以来自任何可以提供定义它的二进制数据的来源。 也许同一个类可能具有来自不同来源的不同实现,例如,程序可能尝试从URL加载某个类的最新版本,但是如果失败则将回退到本地文件。 Java的设计师认为,最好的是,当您尝试运行程序时,不必担心必须跟踪定义正在运行的类的源。 您只需提供完全合格的类名,然后让Java(或更确切地说,其ClassLoader
)完成查找它的艰苦工作即可。
Java编译器采用文件名作为输入,因此采用Foo.java。
Java解释器将使用完全限定的类名称,并在类路径和当前目录中搜索该类。 如果您使用的是Java Foo.class,它将在包“ Foo”中搜索名为“ class”的类,如果该类在默认包中,则返回NoClassDefFoundError,据我从您的示例中了解
Foo.java是文件名,而简单的“ Foo”是类名(不是文件名)。 默认的ClassLoader将在当前工作目录中搜索文件Foo.class并加载它。
补充大卫·扎斯拉夫斯基的解释:
Java源代码也不一定来自.java
文件。 我们可以拥有一个从差异字符流中获取源代码的编译器,如API javax.tools.JavaCompiler
。
cmd行util javac
恰好仅与文件源一起使用,因此需要文件路径。
每种语言都将具有语法和语义,这些语法和语义将在相似各方之间建立规则和理解。 就像英语中的单词,时态,动词等如何简化两个英语会话之间的交流一样。 Java规范建立了语法和语义,编译器只能理解Java文件,而解释器只能理解.class文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.