【问题标题】:Why are filenames in Java the same as the public class name? [closed]为什么Java中的文件名与公共类名相同? [关闭]
【发布时间】:2010-01-25 19:01:22
【问题描述】:

在 Java 中,文件名应与该文件中包含的 public class 的名称相同。为什么这是一个限制?它有什么用途?

【问题讨论】:

  • 这个问题应该改写:为什么任何语言都会故意通过允许任意文件/类命名不匹配而故意让您更难找到您的源代码?

标签: java


【解决方案1】:

Java 有一个有趣的方法:给程序员一个选择只会降低编程体验,去掉选择。

他们在很多地方都这样做了。文件名和包是肯定的,但也不允许在一个文件中有多个公共类(从来都不好),不允许你在文件之间拆分类(该死的很难使用!)等等。

我真希望他们能走得更远一些。没有理由使用公共变量:我从来不需要公共变量,也从未见过一些聪明的程序员认为需要公共变量并且实际上是正确的情况。

我也不介意看到方法/类大小的限制,但这可能会变得粗略(它可以很容易地由代码检查器实现,问题通常是最需要帮助的公司是那些不需要帮助的公司知道他们需要帮助,因此不要使用代码检查器等工具。

这对大多数小型团队来说并不重要,但是当您的团队发展壮大并拥有多个站点,并拥有来自印度、中国和世界各地的顾问的多个站点时,您将开始欣赏这种僵化。


响应 setters/getters 评论:

Java bean 是 Borland 创建的一个可憎的东西,用于破解他们的 GUI,然后改装成 Java。

可怕的想法——从 OO 编程中分心——Getter 和 setter A) 展示了太多的实现,B) 让你思考操作来自另一个对象的数据,而不是要求另一个对象执行操作为你。对于那些还不会在 OO 中思考的人来说,这是一个糟糕的技巧。

Getter 偶尔需要,但除非被视为绝对不可避免,否则不应添加。

应不惜一切代价避免二传手。如果您在构造对象后绝对需要从外部修改状态,请尝试使用构建器模式并保护您的 setter 在执行任何操作后不被调用。

显然,所有事情都有例外,许多“Getter”实际上是关键的对象业务逻辑,例如 String.length() 无论如何实现 String 都需要它,甚至不通过仅返回一个属性来实现 - - 如果您甚至想这样称呼它,这对于“Getter”来说是一个很好的案例。

【讨论】:

  • 在设计 Java 时,getX/setX 范式尚未建立。我认为这是 JavaBeans 必须对接口进行编码的结果,而接口中不能有公共变量。
  • 我希望 Java 也对非公共类强制执行此操作。
  • 实际上存在类和方法大小的限制,它们太大了以至于您在实践中不会遇到它们。
  • 公共变量在类实际上是一个荣耀的结构并且只有公共(且毫无意义)的 getter 和 setter 时很有用
  • 虽然在实践中你是完全正确的,但它偶尔真的很有用,理论上这将是糟糕的 OO,不应该这样做。我已经这样做了几次,但只是作为一个黑客,通常最终会在以后撕掉它。因此,您可以拥有公共变量这一事实只会损害您的代码,我想我坚持我的说法,即它们不应该存在。只有 setter 和 getter 的类或带有公共变量的类是一种非常糟糕的模式。
【解决方案2】:

更具体地说,文件名应该与该文件中的公共类名具有相同的名称,这是告诉JVM这是什么的方式入口点是给你的。

【讨论】:

  • 其实入口点是在jar manifest中指定的。它与Java级别的源文件排列无关。
  • @Antimony,这是如果您必须运行单个 java 文件。甚至你在 Manifest 中提到的入口点也应该有相同的命名约定。
  • 与入口点无关。您可以在名为Bar.java 的文件中创建一个名为Foo 的非public 类,编译它并通过java Foo 运行它。 java 工具不关心该类是否为public,而是通过你给它的类名来确定入口点,而不是源文件的名称(如果你转的话,它甚至不在类字节码中)关闭调试信息)。其他初创公司(运行 jar、servlet)同样以其他方式确定入口点,而不是通过源文件名。
【解决方案3】:

我正要说,这只是必须。但是我看了JLS,并没有那么严格。从 JLS 的角度来看,由编译器决定是否设置这样的限制。

实际上 - 普通编译器确实有这个限制,并且正如其他已经解释的那样,编译器更容易找到编译单元或类加载器找到具有这种限制的类文件。

【讨论】:

  • 就语言规范而言,源代码甚至不需要包含在文件中。这是编译器处理文件中源代码的约定。
【解决方案4】:

这对于定位类很有用。即假设允许不同的文件名,并且如果您创建了一个类的实例,那么编译器必须在所有文件中搜索该类,而不是如果文件名与该类的相同,则定位和使用该类的性能是增加。他们也可能是其他原因。

【讨论】:

    【解决方案5】:

    这只是 Java 的制造商 Sun 设置的 the convention
    目的是组织;原因是每个用 Java 编写代码的人都会有一个一致的文件命名方式。

    【讨论】:

    • 我否决了这个答案,因为它不正确。我的编辑只是更正了这个答案。你决定回滚。现在是你的事了。
    • @nbro:这个答案是 100% 正确的。您的编辑字面上用不同的词表达了相同的意思,同时删除了有用的链接(它已死但现在已修复)。 phisch 的评论也是多余的,因为他的论点与我已经提出的观点相同。
    • @BlueRaja-DannyPflughoeft 这个答案不是 100% 正确的,因此它是不正确的。 “原因是每个用 Java 编写代码的人都会有一个一致的文件命名方式。”。这不是唯一的原因,因此您的回答是不正确的,或者说是误导和不完整的。
    【解决方案6】:

    只要不是公开的一个类可以有一个与其文件名不同的名称。该类也可以有 main 方法。类文件将使用类名而不是源文件名生成。应该使用类名来执行它。

    原因是:默认类是包私有的,因此javac不必从包外找到这个源文件来编译一些其他的java程序。

    【讨论】:

    • 不正确。还有其他限制;见 JLS 7.6。
    【解决方案7】:

    每个公共类必须位于 FileName 与 ClassName 匹配的文件和 Packagename 表示目录结构的包中,以点分形式编写(斜线变为点,如 com/example/app 变为 com.example。应用程序)。

    这个约定不是随机的。编译器必须能够找到源文件,而类加载器必须能够找到实现。匹配包名和类名使这变得非常简单,更重要的是,快速。

    此约定不适用于非公共类。这是因为非公共类的可见性非常有限,只能在定义它们的包中使用。因此,在这两种情况下,编译器和运行时环境都已经找到了正确的文件。

    【讨论】:

    • 非公共、默认访问(“包私有”)类可以在同一个包中的任何地方使用。
    • 是的,这实际上是一个错字。它们可以在包中使用,但不能在其他地方使用。私有类只能在它们定义的文件中使用
    猜你喜欢
    • 1970-01-01
    • 2014-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多