为什么Java文件中只有1个公共类

时间:2010-08-26 18:54:49

标签: java

在任何Java文件中,为什么我们只能有一个名称与Java文件名相同的公共类?

12 个答案:

答案 0 :(得分:28)

它强制所有Java代码以某种方式组织,从长远来看,这有助于提高代码可读性

Java设计人员选择了一种严格的方法来强化他们对良好设计实践的理念,这也是该主题的一部分。与Perl中任何事物的态度形成鲜明对比。

答案 1 :(得分:16)

根据this source,它是为了有效编译:

  

在侧边栏中,它解释了原因:“这   限制尚未得到执行   编译器,虽然它是必要的   高效的包输入“

     

很明显 - 就像大多数事情一样   一旦你知道设计原因 -   编译器必须做一个   额外通过所有   编译单元(.java文件)到   找出哪些课程在哪里,   这将编译   甚至更慢。

这同样适用于IDE中的源文件导入。另一个原因是合理的源尺寸。

答案 2 :(得分:8)

这些是规则。虽然不太正确。您可以在“main”类中定义内部类,如下所示:

public class A {  
   public class B {  
       ...  
   }  
}

答案 3 :(得分:3)

由Heinz Kabutz博士及其出色的newsletter ....

提供
  

为什么每个公共课都是单独的   档案?

     

这是我的一个问题   我经常被问到   课程。到目前为止我还没有   这个问题的答案很好。在   第1节,我们读到:“虽然每个橡树   编译单元可以包含多个   类或接口,最多一个   每个编译的类或接口   单位可以公开“。

     

在侧边栏中,它解释了原因:“这   限制尚未得到执行   编译器,虽然它是必要的   高效的包输入“

     

很明显 - 就像大多数事情一样   一旦你知道设计原因 -   编译器必须做一个   额外通过所有   编译单元(.java文件)到   找出哪些课程在哪里,   这将编译   甚至更慢。

答案 4 :(得分:2)

在任何java编译单元(.java源文件)中,我们只能有一个顶级公共类或接口。

但是每个src文件可以有任意数量的默认类/接口。

<强>为什么:

JLS将选项留给java编译器。并且大多数编译器实现强制使文件名与:

相同

(1)公共类/接口名称

(2)如果有主方法而没有公共类,那么任何名称

(3)如果有主要方法和公共类,则主要方法应该在公共类

(4)如果没有公共类,没有主方法,则任何有效名称可能与文件中的类/接口名称匹配,也可能不匹配。

From(2):如果允许两个公共类,我们应该给文件两个名字,这对文件系统来说是非常无意义的。 从(3):如果允许两个公共类,我们应该有两个主要的方法,这对java来说是非常无意义的

因此,Java源文件只能有一个公共类。

我认为上述4点是编译器强制使编译器和jvm的工作找到特定的java源文件或类文件,因此编译/加载/链接很容易。 Java有这样的内置限制,开发人员应遵循这些限制以获得更好的编程。

资料来源:我的阅读和理解。

答案 5 :(得分:2)

要理解这些限制背后的基本原因,让我们假设编译器没有给出与公共类名相同的文件名命名编译错误。

假设有一个包A

        A
      /   \
file1.java   file2.java

<强> file1.java

package A;

class file1
{
  public static void main(String args[])
  {

  }
}

public class file3
{
 public static void main(String args[])
 {

 }
}

现在我们知道公共类也可以在包外访问,现在它将成为开发人员的责任,使外部世界可以访问它。我们来看看如何:

假设包A只包含Java文件(没有类文件),而包A外的一些类试图访问公共类file3,编译器会首先尝试查找file3.class(不可用),然后它会尝试查找file3.java(不可用)。因此,尽管file3类本质上是公共的,但它对外界是不可见的。因此,如果编译器提出限制,如果文件包含公共类,则应将其命名为与公共类名相同,然后可以解决上述问题,并且开发人员不必考虑将公共类公开给公共类。外面的世界。

编译器还规定每个Java文件应该有一个公共类的限制,以便外部世界可以访问每个公共类。

答案 6 :(得分:1)

Java利用此约定通过从类路径开始并扫描子目录中的包层次结构来查找类/接口字节码。此层次结构的文件系统表示也强制执行一些基本规则。

  1. 任何两个Java类或接口 在同一个包中不能拥有 一样的名字。文件名会 冲突。
  2. 中的任何两个Java包 相同的父包不能 有相同的名字。文件夹路径 会发生冲突。
  3. 一个类可以看到同一个包中的所有类而无需修改 到类路径。

答案 7 :(得分:1)

要在编译器和程序员之间有一个理解。规则是源代码必须至少有一个公共类,并且该类必须包含main函数。所以编译器可以访问(公共)没有任何混淆/限制类和类名称命名为类文件。也因为这个类包含main(),执行类文件将给出正确的流程

答案 8 :(得分:0)

它可以在编译期间(import指令)更有效地查找源( .java)和编译( .class)文件,并在执行期间更有效地进行类加载。这个想法是:如果您知道类的名称,您就知道每个类路径条目应该在哪里找到它。无需索引。

答案 9 :(得分:0)

我认为这可能是一个可能的原因。 java文件中只能有一个公共类,因为java文件的名称与公共类的名称相同。显然我们不能拥有两个不同名称的文件。

答案 10 :(得分:0)

这是它的设计方式,我不确定原因是否已记录在案。但是,这样做有一个很好的理由。假设在名为Y.java的文件中有两个公共类Y和Z。现在,假定使用X的类是另一个X。现在,当我们编译X时,编译器首先尝试定位Z.class,如果找不到它,则尝试定位Z.java,以便它可以自动编译它。 。但是,由于我们只有Y.java,因此无法找到类Z,因此会出现编译错误。因此,我们确实需要将它们放在单独的文件中。

答案 11 :(得分:0)

带有类的公共修饰符暴露于世界,这意味着该包外部的任何其他类也可以访问它来解决依赖关系。 现在,此包含多个类的依赖关系链已进行两次验证-一种是在编译时(验证了一层依赖关系),另一种是在执行时(验证了整个依赖关系链)。

现在假设存在一个公共类(类A),其源文件名与类名有所不同。现在,如果其他某个类(例如,类B)依赖于它,则在编译类B时,java编译器肯定会检查该类A的位置,并且该编译器必须通过所有软件包来寻找类A,这很费时间。

现在假设在相同的情况下,我们将类A的源文件名指定为A.java,然后在编译类B时,编译器将搜索类A,并且只需要查找名称为A.java的源文件即可。 ,因此它不需要遍历所有软件包(可能包含多个类),现在只搜索存在源文件A.java的那个软件包。

因此从编译时开始,如果查看一个源文件,则性能点应该具有一个公共类。