java 程序是从一个 public 类的 main 函数开始执行的,(其实是main线程),就像 C 程序 是从 main() 函数开始执行一样。 只能有一个 public 类是为了给类装载器提供方便。 一个 public 类只能定义在以它的类名为文件名的文件中。
每个编译单元(文件)都只有一个 public 类。因为每个编译单元都只能有一个公共接口,用 public 类来表现。该接口可以按照要求包含众多的支持包访问权限的类。如果有一个以上的 public 类,编译器就会报错。 并且 public类的名称必须与文件名相同(严格区分大小写)。 当然一个编译单元内也可以没有 public 类。
当这个源文件中有一个public修饰的类时,源文件的名称必须和public修饰的类的类名完全一致(区分大小写)。为什么这时的取名要完全一致呢?
很简单,因为jvm虚拟机为了提高查找类的速度,使用import语句导入的时候,只会导入对应空间的文件名所对应的class文件,而public文件是大家都要使用的,因此直接导入这个类名对应的class文件即可。(如果编译单元中包含了public类,那么该类对应的字节码文件当需要被类加载器加载的,这时候就需要让类加载器知道该字节码文件的位置,所以就要确保该类与Java文件名称一致。同时,如果有两个public类在同一个文件中,而一个文件只能有一个名称,故两个public类的名称就不能同时和文件名一样,这就造成至少其中有一个public类在编译的时候编译不通过,产生类似的提示(对于一个public类,它是可以被项目中任何一个类所引用的,只需在使用它前import一下它所对应的class文件即可,将类名与文件名一一对应就可以方便虚拟机在相应的路径(包名)中找到相应的类的信息。如果不这么做的话,就很难去找,而且开销也会很大)。)
当这个源文件中一个public修饰的类都没有时,源文件的名称可以不一致,但必须符合命名规则。这里为什么可以不一致呢?
Java编译器在编译的时候,如果整个Java文件(编译单元)都没有public类(对外的公开接口类),类加载器子就无需从这方面直接去加载该编译单元产生的所有的字节码文件(.class文件),那么也就是无需去寻找编译后字节码文件存放位置。而类名和文件名一致是为了方便虚拟机在相应的路径中找到相应的类所对应的字节码文件。所以在没有public类的Java文件中,文件名和类名都没什么联系。