一个java源文件为什么只能有一个public类呢?当这个类被修饰public的话,为什么源文件名必须要与类名相同呢?
Java编程思想中的一段话:
当编写一个java源代码文件时,此文件通常被称为编译单元(有时也被称为转译单元)。每个编译单元都必须有一个后缀名.java,而在编译单元内则可以有一个public类,该类的名称必须与文件的名称相同(包括大小写,但不包括文件的后缀名.java)。每个编译单元只能有一个public类,否则编译器就不会接受。如果在该编译单元之中还有额外的类的话,那么在包之外的世界是无法看见这些类的,这是因为它们不是public类,而且它们主要用来为主public类提供支持。
理解:
每编写一个Java文件就是Java编译器编译Java源代码的一个编译单元,具体怎么编译呢?这个就需要去了解Java编译器的工作原理了。编译器每编译一个.java文件(编译单元),对应着.java文件中的每个类都会有一个输出文件,而该输出文件的名称与.java文件中每个类的名称相同,只是多了一个后缀名.class。因此,在编译少量.java文件之后,会得到大量的.class文件。在.java文件中,不是必须含有public类的。public类只是用来表示编译单元中存在公开接口。
但如果含有public类,最多只能有一个,必须名字和文件名一样。因为编译的时候Java编译器会判断如果存在public类,该类当作这个编译单元的对外接口,类加载器需要把该类加载。对于一个public类,它是可以被项目中任何一个类所引用的,只需在使用它前import一下它所对应的class文件即可,将类名与文件名一一对应就可以方便虚拟机在相应的路径(包名)中找到相应的类的信息。如果不这么做的话,就很难去找,而且开销也会很大。运行的时候则是调用main()函数运行的。
个人总结:
1、Java编译器在编译的时候,如果整个Java文件(编译单元)都没有public类(对外的公开接口类),类加载器子就无需从这方面直接去加载该编译单元产生的所有的字节码文件(.class文件),那么也就是无需去寻找编译后字节码文件存放位置。而类名和文件名一致是为了方便虚拟机在相应的路径中找到相应的类所对应的字节码文件。所以在没有public类的Java文件中,文件名和类名都没什么联系。
2、如果编译单元中包含了public类,那么该类对应的字节码文件当需要被类加载器加载的,这时候就需要让类加载器知道该字节码文件的位置,所以就要确保该类与Java文件名称一致。同时,如果有两个public类在同一个文件中,而一个文件只能有一个名称,故两个public类的名称就不能同时和文件名一样,这就造成至少其中有一个public类在编译的时候编译不通过,产生类似的提示
3补充一点:如果一个public类的内部类存在的话,那么会生成otherClass&InnerClass.class文件,其实就是为了识别内部类.
java解释器的运行过程如下:首先,找出环境变量CLASSPATH(可以通过操作系统来设置,有时也可通过安装程序-用来在你的机器上安装java或者基于java的工具-来设置)。CLASSPATH包含一个或多个目录,用作查找.class文件的根目录。从根目录开始,解释器获取包的名称并将每个句点替换成反斜杠,以从CLASSPATH根中产生一个路径名称(于是,package foo.bar.baz就变成了foo\bar\baz或foo/bar/baz或其他,这一切取决于操作系统)。得到的路径会与CLASSPATH中的各个不同的项相连接,解释器就在这些目录中查找与你所要创建的类名称相关的.class文件(解释器还会去查找某些涉及java解释器所在位置的标准目录)