在Java中,您可以在单个文件中定义多个顶级类,前提是其中一个是公共的(请参阅JLS §7.6) . 见下面的例子 .
-
这种技术是否有一个整洁的名称(类似于
inner
,nested
,anonymous
)? -
JLS说系统 may 强制执行这些辅助类不能
referred to by code in other compilation units of the package
的限制,例如,它们不能被视为包私有 . 这真的在Java实现之间发生了变化吗?
例如,PublicClass.java:
package com.example.multiple;
public class PublicClass {
PrivateImpl impl = new PrivateImpl();
}
class PrivateImpl {
int implementationData;
}
7 回答
我对这种技术的建议名称(包括单个源文件中的多个顶级类)将是“混乱” . 说真的,我认为这不是一个好主意 - 在这种情况下我会使用嵌套类型 . 然后,它仍然很容易预测它所在的源文件 . 我不相信这种方法的官方术语 .
至于这实际上是否在实现之间发生了变化 - 我非常怀疑它,但如果你首先避免这样做,你将永远不需要关心:)
javac没有主动禁止这一点,但它确实有一个限制,几乎意味着你永远不想从另一个文件引用顶级类,除非它与它所在的文件具有相同的名称 .
假设您有两个文件,Foo.java和Bar.java .
Foo.java包含:
Bar.java包含:
公共类酒吧
class Baz
我们还要说所有类都在同一个包中(并且这些文件位于同一目录中) .
如果Foo.java引用Baz而不是Bar并且我们尝试编译Foo.java会发生什么?编译失败,出现如下错误:
如果你考虑一下,这是有道理的 . 如果Foo.java引用了Baz,但是没有Baz.java(或Baz.class),javac怎么知道要查看哪个源文件?
如果您改为告诉javac同时编译Foo.java和Bar.java,或者即使您之前编译过Bar.java(留下了javac可以找到它的Baz.class),那么这个错误就会消失 . 但是,这会使您的构建过程感觉非常不可靠和不稳定 .
因为实际的限制,更像是“不要从另一个文件引用顶级类,除非它与它所在的文件具有相同的名称,或者你也指的是同一个文件中的一个类名称与文件“有点难以理解的东西相同,人们通常会选择在每个文件中放置一个顶级类的更简单(尽管更严格)的约定 . 如果您改变主意是否应该公开课程,这也会更好 .
有时,每个人都以某种特定的方式做某事真的有充分的理由 .
我相信你只是简单地称之为
PrivateImpl
:non-public top-level class
. 您也可以声明non-public top-level interfaces
.例如,SO上的其他地方:Non-public top-level class vs static nested class
至于版本之间的行为变化,有关于1.2.2中的"worked perfectly"的讨论 . 但在太阳的论坛中停止了1.4的工作:Java Compiler - unable to declare a non public top level classes in a file .
你可以像这样拥有任意数量的课程
多级单文件演示 .
我不知道有哪些没有这个限制 - 所有基于文件的编译器都不允许你在类名不同的文件中引用源代码类 . (如果编译多类文件,并将类放在类路径上,那么任何编译器都会找到它们)
根据Effective Java第2版(第13项):
根据成员类是否需要访问封闭实例(第22项),嵌套类可以是静态的或非静态的 .
是的,你可以外部公共类上的公共静态成员,如下所示:
和另一个引用上述内容的文件:
把它们放在同一个文件夹中 . 编译:
并运行: