我有一个名为Test.java
的文件,并且里面有以下代码。
public class Abcd
{
//some code here
}
现在这个类无法编译,但是当我移除public
修饰符时,它可以成功编译。
为什么Java允许我们编译一个类名与文件名不同的类(当它不是public类)?
我知道这是一个新手问题,但我找不到一个好的解释。
我有一个名为Test.java
的文件,并且里面有以下代码。
public class Abcd
{
//some code here
}
现在这个类无法编译,但是当我移除public
修饰符时,它可以成功编译。
为什么Java允许我们编译一个类名与文件名不同的类(当它不是public类)?
我知道这是一个新手问题,但我找不到一个好的解释。
这个规则的理由是允许一个.java
文件中有多个顶层类。
许多类(例如事件监听器)仅在本地使用,早期版本的Java不支持嵌套类。如果没有这个“文件名=类名”的规则放宽,每个这样的类都需要自己的文件,结果会不可避免地导致无休止的小.java
文件的大量增加,以及紧密耦合代码的散布。
一旦Java引入了嵌套类,这个规则的重要性显著下降。今天你可以浏览许多Java文件,从未碰到过一个利用它的。
原因与门牌相同。如果有人正式居住在办公室(声明为公共场所),他/她的姓名必须出现在门牌上,比如“Alex Jones”或“Colombo侦探”。如果有人只是访问房间、与官员交谈或清洁地板,他们的名字就不需要正式放在门上。相反,门上可以写着“设施”或“会议室”等字样。
Java规范规定一个文件中只能有最多一个公共类,此时类名应与文件名相匹配。所有非公共类都可以拥有任何名称,无论文件名如何。
我认为,允许匿名类是嵌套类的前提条件。特别是匿名类,它极大地减少了所需的 .java 文件数。如果没有这种支持,您需要将许多单一方法接口实现放在它们自己的单独文件中,从主要使用它们的类中分离出来。(我特别考虑了 action listeners)
在 Oracle 网站的嵌套类 Java 教程中有对所有嵌套类的很好解释,其中包括每个示例。它还有一个它们有用的原因,我会引用:
为什么使用嵌套类?
使用嵌套类的强制性原因包括以下内容:
逻辑上分组只使用一个位置的类的方式: 如果一个类只对另一个类有用,那么将其嵌入该类并将两者保持在一起是合理的。嵌套这样的“辅助类”可以使其包更加简化。
增加封装性: 考虑两个顶层类 A 和 B,其中 B 需要访问 A 的成员,否则将声明为私有。通过将类 B 隐藏在类 A 中,A 的成员可以被声明为私有,并且 B 可以访问它们。此外,B 本身可以对外界隐藏。
它可以导致更易读和易维护的代码: 将小类嵌套在顶级类中,将代码放置在使用它的地方附近。
(我强调的)
我不熟悉早期的 Java 规范,但快速搜索显示内部类是在 Java 1.1 中添加的。
我持相反观点。程序员应该独立选择类名和文件名才是自然的状态。可能出于简化编译时从包外查找公共类的目的,有一个特殊限制,即公共类必须在与其对应的文件中。
Foo
,标识符FOO
、foo
、fOo
等都将是“未定义”的,即使它们存在于外部范围内。这样的设计将消除文件名的大小写敏感问题。 - supercat