我有一个文件Test.java和其中的以下代码。
public class Abcd
{
//some code here
}
现在,该类无法编译,但是当我删除public修饰符时,它可以正常编译。
Java背后的原因是,允许我们编译一个与文件名不公开的文件名不同的类名。
我知道这是一个新手问题,但我找不到很好的解释。
我有一个文件Test.java和其中的以下代码。
public class Abcd
{
//some code here
}
现在,该类无法编译,但是当我删除public修饰符时,它可以正常编译。
Java背后的原因是,允许我们编译一个与文件名不公开的文件名不同的类名。
我知道这是一个新手问题,但我找不到很好的解释。
Answers:
基本原理是每个.java文件允许一个以上的顶级类。
许多类(例如事件侦听器)仅在本地使用,并且Java的最早版本不支持嵌套类。如果不放宽“文件名=类名”规则,则每个此类都将需要自己的文件,不可避免的结果是小.java文件的无休止扩散和紧密耦合的代码的分散。
Java引入嵌套类后,此规则的重要性就大大降低了。今天,您可以浏览成百上千个Java文件,而永远不会选择利用它的文件。
原因与门板相同。如果某人正式居住在办公室(已宣布为公众),则其姓名必须在门标签上。像“亚历克斯·琼斯”或“侦探科伦坡”。如果有人只是去房间,与官员交谈或打扫地板,则不必将他们的名字正式放在门上。取而代之的是,门可以显示“实用程序”或“会议室”。

Java规范规定每个文件最多只能有一个公共类。在这种情况下,类名应与文件名匹配。不论文件名如何,所有非公共类都可以具有任何名称。
我认为允许它们是嵌套类的先决条件。特别是,匿名类极大地减少了所需的.java文件数量。如果没有对此的支持,您将需要在与使用它们的主类不同的单独文件中的许多单方法接口实现。(我特别考虑动作监听器)
Oracle网站上的Nested Classes Java教程对所有嵌套类都有很好的解释,其中每个示例都有示例。还有一个有用的理由,我在此引用:
为什么要使用嵌套类?
使用嵌套类的令人信服的原因包括:
这是一种对仅在一个地方使用的类进行逻辑分组的方法:如果一个类仅对另一个类有用,那么将其嵌入该类并将两者保持在一起是合乎逻辑的。嵌套此类“帮助程序类”可使它们的程序包更加简化。
它增加了封装:考虑两个顶级类A和B,其中B需要访问A的成员,否则它们将被声明为私有。通过将类B隐藏在类A中,可以将A的成员声明为私有,而B可以访问它们。另外,B本身可以对外界隐藏。
这可能会导致代码更具可读性和可维护性:在顶级类中嵌套小类会使代码更靠近使用位置。
(强调我的)
早期我并不熟悉Java规范,但是快速搜索显示Java 1.1中添加了内部类。
我反过来看。事务的自然状态是程序员独立选择类名和文件名。为了简化在编译过程中从包外部查找公共类,可能有一个特殊限制,即公共类必须位于具有相应名称的文件中。
请注意,Java区分大小写,但文件系统不必区分大小写。如果文件的基本名称是“ abcd”,但类是“ Abcd”,那么这是否符合不区分大小写的文件系统上的规则?当移植到区分大小写的代码时肯定不会。
或假设您碰巧有一个名为ABCD的类和一个Abcd类(让我们进入一个坏主意:它可能会发生),然后将该程序移植到不区分大小写的文件系统中。现在,您不仅必须重命名文件,而且还必须重命名类!
或者如果没有文件怎么办?假设您有一个Java编译器,可以在标准输入上接受输入。那么,该类必须命名为“ StandardInput”吗?
如果您理性地探索了要求文件名跟随类名的含义,那么您会发现这是一个坏主意。
Foo被宣布,标识符FOO,foo,fOo,等会全部“未定义”,即使他们在外范围内的存在。这样的设计将消除文件名区分大小写的问题。