为什么您想要一个没有声明公共类的Java文件?

为什么您想要一个没有声明公共类的Java文件?,java,class,Java,Class,我正在为SCJP资格阅读的书中有一条声明,它说: 没有公共类的文件没有 命名限制 这让我问,你为什么要这么做? 如果没有公共类,那么其他类如何导入和使用该文件?我能看到的唯一目的是如果文件本身独立运行,这也可能是奇怪的,例如在一个文件中包含整个应用程序,这对类也是有效的。您可以在同一个包中使用包私有类。(在这种情况下,您不必导入它,因为它在同一个包中。) 例如,JapaneseImperialCalendar类是包私有的,因为它只在Calendar.createCalendar(..)中使用-它

我正在为SCJP资格阅读的书中有一条声明,它说:

没有公共类的文件没有 命名限制

这让我问,你为什么要这么做?

如果没有公共类,那么其他类如何导入和使用该文件?我能看到的唯一目的是如果文件本身独立运行,这也可能是奇怪的,例如在一个文件中包含整个应用程序,这对类也是有效的。您可以在同一个包中使用包私有类。(在这种情况下,您不必导入它,因为它在同一个包中。)

例如,
JapaneseImperialCalendar
类是包私有的,因为它只在
Calendar.createCalendar(..)
中使用-它不是公共API的一部分。您不能直接实例化日文日历,但仍然可以通过其接口使用它。对于所有通过
collections.unmodifiableList(..)
等方法获得的不可修改集合,情况也是如此-它们是包私有的

因此
JapaneseImperialCalendar
.java
文件可能是任意的。但是,建议不要偏离以类名命名包私有文件的既定做法。

从中,您有公共类和包类。包类被认为是“私有的”,因此您只能在包本身中使用它们。这是默认设置,即未指定公共


当然,公共类是可以在任何地方创建的类。

您可以创建一个名为
package info.java
的文件,该文件只包含
package
语句。JavaDoc1.5+工具将此包语句上的javadoc注释与
package.html
文件完全相同。此外,您可以将包级别的注释(如
@Generated
)添加到此语句中,这在
package.html
中是无法做到的


由于
package info
不是有效的Java标识符,因此此文件不存在与现有Java类冲突的风险(即向后兼容)。

我不同意非限制。每个java文件应该只包含一个顶级类,并且文件名应该与类名相同(public或not)。我不认为javac会非常喜欢这个(或者任何人)


7.2主机对包的支持

每台主机决定如何安装软件包, 编译单元和子包是 创建和存储,以及 编译单元是可观察的 (§7.3)在特定汇编中

7.2.1在文件系统中存储包

作为一个非常简单的例子


源文件和类文件都必须具有 标识类的根名称。 例如,一个名为MyClass的类 将写入源文件中 调用MyClass.java并编译成 一个名为 我的班级


虽然我回答这个问题已经很晚了,但这肯定会有很大帮助。如果我没有错的话,你的具体问题可以归结为这样一个问题:没有显式修饰符的类的意义是什么

看看java.util包中的这个类-

class JumboEnumSet<E extends Enum<E>> extends EnumSet<E>
类JumboEnumSet扩展枚举集
另请参见同一软件包中的-

class RegularEnumSet<E extends Enum<E>> extends EnumSet<E>
类RegularEnumSet扩展了EnumSet
您可以看到,它们都是用声明的,没有显式修饰符。您是否想知道为什么会有包私有限制?以下是Joshua Bloch的《高效Java第二版》一书中的原因#Item1

java.util.EnumSet(第32项),在发行版中引入 1.5,有 没有公共构造函数,只有静态工厂。它们返回两种实现中的一种,具体取决于基础枚举类型的大小:如果它包含64个或更少的元素,如下所示 大多数枚举类型都会返回一个RegularEnumSet 实例,该实例由 单长;如果枚举类型包含65个或更多元素,则工厂将返回一个由长字符串支持的JumboEnumSet实例 数组

他进一步补充说,迅速前进-

这两个实现类的存在是不可见的 客户。如果RegularEnumSet停止为 如果枚举类型很小,则可以在将来的版本中消除它,而无需 不良影响。类似地,未来的版本可以添加第三个或第四个 EnumSet的实现,如果它被证明对性能有益。 客户机既不知道也不关心他们得到的对象的类 从工厂回来;他们只关心它是 枚举集


实际上,这是一个非常合适的例子,说明了为什么这样的文件没有命名限制。文件名甚至不是一个合法的类名,因此它不可能是一个包含类的文件(但它仍然是编译器将根据JLS中列出的规则处理的*.java)。这是允许的,不管喜欢与否。这在总体上是否有意义是另一个问题case@bozho文件名约定的原始来源是什么?可能已经很久了。我不知道它是怎么做到的:)@bozho JSL不会规定这样的事情。为了加强保持既定的命名惯例以防万一,还请注意,“主机系统可能……强制执行限制,即如果在文件中找不到类型[使用该命名约定],则这是一个编译时错误。”即使在类型仅“由声明该类型的包的其他编译单元中的代码引用”(包私有)的情况下。
class RegularEnumSet<E extends Enum<E>> extends EnumSet<E>