在Java 中,您可以在一个文件中定义多个顶级类,前提是其中最多有一个是公共(public)的(参见JLS §7.6)。例如,请参见下文。
这个技术有没有一个简洁的名字(类似于inner
、nested
、anonymous
)?
JLS 表示系统可能强制限制这些二级类不能被包的其他编译单元中的代码引用
,例如,它们不能被视为包私有(private)。这真的会在 Java 实现之间发生变化吗?
例如,PublicClass.java:
package com.example.multiple;
public class PublicClass {
PrivateImpl impl = new PrivateImpl();
}
class PrivateImpl {
int implementationData;
}
Javac 并没有主动禁止这一点,但它确实有一个限制,这几乎意味着您永远不想从另一个文件中引用顶级类,除非它具有相同的命名为它所在的文件。
假设您有两个文件,Foo.java
和 Bar.java
。
Foo.java
包含:
Bar.java
包含:
假设所有的类都在同一个包中(并且文件在同一个目录中)。
如果 Foo
引用 Baz
而不是 Bar
并且我们尝试编译 Foo.java
会发生什么?编译失败并出现如下错误:
Foo.java:2: cannot find symbol
symbol : class Baz
location: class Foo
private Baz baz;
^
1 error
如果您考虑一下,这是有道理的。如果Foo
引用了Baz
,但是没有Baz.java
(或者Baz.class
),怎么可能javac 知道要查看什么源文件吗?
如果您改为告诉 javac 同时编译 Foo.java
和 Bar.java
,或者如果您之前编译过 Bar.java
(将 Baz.class
留在 javac 可以找到它的地方),或者即使 Foo
碰巧引用除了 Baz
之外的 Bar
,则此错误消失。然而,这会让您的构建过程感觉非常不可靠和不稳定。
因为实际的限制,这更像是“不要引用另一个文件中的顶级类,除非它与它所在的文件同名,或者您还引用了另一个名为与该文件中的那个文件相同”有点难以遵循,人们通常采用更直接(尽管更严格)的约定,即在每个文件中只放置一个顶级类。如果您改变了关于是否应该公开类(class)的想法,这也会更好。
javac 的较新版本也可以在这种情况下使用 -Xlint:all
产生警告:
auxiliary class Baz in ./Bar.java should not be accessed from outside its own source file
有时每个人都以特定的方式做某事确实有充分的理由。
我是一名优秀的程序员,十分优秀!