为什么Java允许我们编译名称与文件名不同的类?

use*_*434 170 java

我有一个文件Test.java和里面的代码.

public class Abcd
{
        //some code here

}
Run Code Online (Sandbox Code Playgroud)

现在这个类没有编译,但是当我删除public修饰符时,它编译得很好.

Java背后的原因是什么允许我们在不公开时编译与文件名不同的类名.

我知道这是一个新手问题,但我无法找到一个好的解释.

Mar*_*nik 323

理由是每个.java文件允许多个顶级类.

许多类(如事件侦听器)仅供本地使用,最早的Java版本不支持嵌套类.如果没有"文件名=类名"规则的放宽,每个这样的类都需要自己的文件,不可避免的结果是小.java文件的无限扩散和紧密耦合的代码的分散.

一旦Java引入了嵌套类,这条规则的重要性就会大大降低.今天,您可以浏览数百个Java文件,而不会利用它来利用它.

  • +1,这实际上提供*原因*,这是问题. (59认同)
  • Emacs(或Vim,选择你的毒药)和Unix shell实用程序的组合可能并不像现代IDE一样触手可及,而且它们当然难以学习,但它们有两个*压倒性优势*与我曾尝试过的每个IDE相比:它们永远不会崩溃,无论代码库有多大,它们都可以跟上我的打字. (5认同)
  • 尤其是+1的历史信息 - 我怀疑随着嵌套/匿名类的出现,如果现在做出相同的决定(不关心向后兼容性),那么只允许一个顶级类更有意义文件. (4认同)
  • @Val否认其他人宁愿使用文本编辑器和CLI工具来开发,因为你喜欢的IDE存在就像说创建IDE没有意义,因为你可以在没有它的情况下进行开发.优秀的开发人员使用这两种方法来创建高质量的代码; 并且唯一比所有开发者解决其中一个并且唱kumbaya的几率小的事情是我们都同意单一最佳编程语言的几率. (3认同)

exe*_*ook 79

原因与门板相同.如果某人正式居住在办公室(公开宣布),他/她的名字必须在门牌上.像"亚历克斯琼斯"或"侦探科伦坡".如果有人只是去房间,与官员交谈或清理地板,他们的名字不一定要正式上门.相反,门可以读作"公用事业"或"会议室".

官方名称或MyClass.java 会议室或Test.java

  • 绝对是一个有趣的比喻; 通过对它如何直接相关的一点解释可能会更好.OP可能在建立连接时遇到一些困难(虽然我完全理解) (4认同)
  • @AndrewBarber我不认为这个比喻真的适合,因为它没有为一个公共类建模,与几个包私有类共享文件.这就像门板上写着"Heather Santee,经理",但房间实际上包含希瑟和她的两个秘书. (4认同)

And*_*san 29

Java规范声明每个文件最多只能有一个公共类.在这种情况下,类名应与文件名匹配.无论文件名是什么,都允许所有非公共类具有任何名称.

  • 但"Java背后的原因是什么让我们这么做? (19认同)
  • @MarounMaroun但是没有阻止我们的原因是什么? (8认同)
  • 我的2美分:也许它是这样设计的,可以更快地在classpath中定位类.使用此约定,检查文件名/路径就足以进行类发现.如果没有这种约定,classpath类加载器可能需要打开和解析文件才能找到类 (2认同)

Jos*_*non 13

我认为允许它们是嵌套类的先决条件.特别是匿名类可以显着减少所需的.java文件数量.如果不支持这一点,你需要在他们自己使用的主类的独立文件中进行大量的单一方法接口实现.(我特别想到动作监听器)

Oracle网站上的嵌套类 Java教程中对所有嵌套类有一个很好的解释,其中包含每个嵌套类的示例.它也有一个有用的原因,我将引用它:

为什么使用嵌套类?

使用嵌套类的令人信服的理由包括:

  • 它是一种逻辑分组仅在一个地方使用的类的方法:如果一个类只对另一个类有用,那么将它嵌入该类并将两者保持在一起是合乎逻辑的.嵌套这样的"帮助类"使得它们的包更加简化.

  • 它增加了封装:考虑两个顶级类A和B,其中B需要访问A的成员,否则这些成员将被声明为私有.通过将类B隐藏在类A中,可以将A的成员声明为私有,并且B可以访问它们.另外,B本身可以隐藏在外面.

  • 它可以带来更易读和可维护的代码:在顶级类中嵌套小类会使代码更接近于使用它的位置.

(强调我的)

早期我不熟悉Java规范,但快速搜索显示Java 1.1中添加了内部类.


Pat*_*han 12

我反过来看它.自然状态是程序员独立选择类名和文件名.可能为了简化在编译期间从包外部查找公共类,有一个特殊限制,即公共类位于具有相应名称的文件中.