Java:一个文件中的多个类声明

问题

在Java中,你可以在单个文件中定义多个顶级类,前提是其中一个是公共的(参见JLS §7.6)。见下面的例子。

  • 这种技术是否有一个整洁的名称(类似于内部,嵌套,匿名)?
  • JLS表示系统可以强制限制这些二级类不能被包的其他编译单元中的代码引用,例如,它们不能被视为包私有。这实际上是Java实现之间的变化吗?

例如,PublicClass.java:

package com.example.multiple;

public class PublicClass {
    PrivateImpl impl = new PrivateImpl();
}

class PrivateImpl {
    int implementationData;
}

#1 热门回答(116 赞)

javac没有主动禁止这一点,但它确实有一个限制,几乎意味着你永远不想从另一个文件引用顶级类,除非它与它所在的文件具有相同的名称。

假设你有两个文件,Foo.java和Bar.java。

Foo.java包含:

  • 公共课Foo

Bar.java包含:

  • 公共级酒吧
  • 班级Baz

我们还要说所有类都在同一个包中(并且文件位于同一目录中)。

如果Foo.java引用Baz而不是Bar并且我们尝试编译Foo.java会发生什么?编译失败,出现如下错误:

Foo.java:2: cannot find symbol
symbol  : class Baz
location: class Foo
  private Baz baz;
          ^
1 error

如果你考虑一下,这是有道理的。如果Foo.java引用Baz,但是没有Baz.java(或Baz.class),javac怎么知道要查找哪个源文件?

如果你改为告诉javac同时编译Foo.java和Bar.java,或者你以前编译过Bar.java(留下了javac可以找到的Baz.class),那么这个错误就会消失。但是,这会使你的构建过程感觉非常不可靠和不稳定。

因为实际的限制,更像是"不要从另一个文件引用顶级类,除非它与它所在的文件具有相同的名称,或者你也指的是同一个文件中的一个类名称与文件相同的东西"很难理解,人们通常会采用更直接(但更严格)的惯例,即在每个文件中放置一个顶级类。如果你改变主意是否应该公开课程,这也会更好。

有时,每个人都以某种特定的方式做某事真的有充分的理由。


#2 热门回答(112 赞)

我对这种技术的建议名称(包括单个源文件中的多个顶级类)将是"混乱"。说真的,我认为这不是一个好主意 - 我会在这种情况下使用嵌套类型。然后,它仍然很容易预测它所在的源文件。我不相信这种方法的官方术语。

至于这实际上是否在实现之间发生了变化 - 我非常怀疑它,但如果你首先避免这样做,你将永远不需要关心:)


#3 热门回答(21 赞)

我相信你只需要致电889603024:anon-public top-level class。你也可以声明non-public top-level interfaces

例如,SO上的其他地方:非公共顶级类vs静态嵌套类

至于版本之间的行为变化,有关于1.2.2中"完美运行"的内容的讨论。但在太阳的论坛中停止了工作:Java Compiler - unable to declare a non public top level classes in a file