为什么我不能给一个类取与文件名不同的名称?

9

当我想创建一个Java类时,它会自动生成与类名相同的文件。

但是,它生成类时,文件名可能不同于类名。我错过了什么吗?

alt text
(来源:screencast.com)

alt text


@uzay95:我知道这是怎么回事。我总是有同样的感觉,并且总是得到相同的答案。 - Pratik Deoghare
2
+1,这个问题的图形非常棒。你是怎么创建它的? - Pratik Deoghare
我使用 Jing 进行捕捉和绘制这些红色线条 :) - uzay95
4个回答

10

引用自Java语言规范7.6顶层类型声明一节:

当软件包存储在文件系统(§7.2.1)中时,主机系统可以选择执行以下限制:如果一个类型没有在类型名称加上扩展名(例如.java.jav)的文件中找到,那么编译时会出错,如果以下两种情况之一成立:
  • 该类型被声明在包的其他编译单元中的代码所引用。
  • 该类型被声明为public(因此可能可以从其他包的代码访问)。
这个限制意味着每个编译单元最多只能有一个这样的类型。这个限制使得Java编程语言的编译器或Java虚拟机的实现可以很容易地在包中找到命名类;例如,公共类型wet.sprocket.Toad的源代码将在wet/sprocket目录下的文件Toad.java中找到,相应的目标代码将在同一目录下的文件Toad.class中找到。
当软件包存储在数据库(§7.2.2)中时,主机系统不能强制执行这些限制。实际上,许多程序员选择将每个类或接口类型放在自己的编译单元中,无论它是否是public,或者是否被其他编译单元中的代码所引用。

1
谢谢你是这个讨论串中唯一一个找到相关语言规范并引用的人,而不是凭空说话的人。:) - delfuego
无论如何,JLS说“可能选择执行*”,因此它仍然只是一种惯例,而不是硬性规定。 - skaffman

8

因为语言设计者这么说。这很简单。这是一种惯例,他们强制你遵循它。


4
这简化了类加载。 - Daniel Rikowski
当Java本身创建一个类(如图2所示)时,它会以不同的名称命名。我的意思是类名和包含该类的文件名是不同的。仔细看看图2。你会发现右侧的文件名是“Book_1.java”,而类名是“Book”。你明白我的意思了吗? - uzay95
@uzay95,Java不会创建类。是你的工具/IDE创建的。我不知道这个工具是什么,但它看起来像一个bug。要么你正在尝试在同一个包中创建太多Book类。 - Glen
这是NetBeans 6.7.1,它提供了一个名为Book的类名,即使它已经存在于包中。 - uzay95

4

语言规范本身并没有规定这一点(我刚刚查看了一下,没有找到任何相关的参考),但通常由工具来执行。这使得工具的依赖管理更加容易,因为它知道如果A类引用B类,它就可以在哪里查找B类。这个约定也扩展到目录结构反映包结构,但同样,这只是一个约定。


+1 - 这绝对是一种惯例,而不是语言限制。 - Stephen C
3
几乎所有编译器和工具都强制执行这个约定,这使它实际上成为一种语言限制,即使该约定没有被Java语言规范所规定。 - Joey
2
请参考Pascal Thivent的下面的答案;JLS中确实有关于这个的引用。 - delfuego
好的,足够正确,就在那里。我只是没看够仔细。 - skaffman

1
如果我能改变世界,我希望C#设计师也能这样做。强制程序员不要创建file classes.cs并将所有代码放入其中可以节省多少时间呢?这难道不像if语句需要括号一样的要求吗?为什么语言要强迫我做这种愚蠢的事情呢?
if (true)
{

}

替代

if true
{

}

:-)


更易读?为谁而更易读?当我打开项目时,我应该能够非常容易地通过类名找到文件,并通过文件名找到类,如果工具强制人们遵循这些规则,我会投赞成票。 - Sergey Mirvoda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接