在Java中,你可以在一个文件中定义多个顶级类,只要其中最多有一个是公共的(参见JLS§7.6)。请看下面的例子。

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

例如,PublicClass.java:

package com.example.multiple;

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

class PrivateImpl {
    int implementationData;
}

当前回答

我相信您可以将PrivateImpl定义为:一个非公共顶级类。您还可以声明非公共顶级接口。

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

至于不同版本之间的行为变化,有关于在1.2.2中“完美工作”的讨论。但是在sun的论坛:Java编译器1.4中停止工作-无法在文件中声明非公共顶级类。

其他回答

1.这种技术是否有一个整齐的名称(类似于内部的、嵌套的、匿名的)?

多类单文件演示。

2.JLS表示,系统可能会强制限制这些二级类不能被包的其他编译单元中的代码引用,例如,它们不能被视为包私有。这真的是Java实现之间的变化吗?

我不知道有哪个没有这个限制——所有基于文件的编译器都不允许你引用与类名不同的文件中的源代码类。(如果你编译一个多类文件,并把类放在类路径上,那么任何编译器都能找到它们)

我建议将这种技术(包括在一个源文件中包含多个顶级类)命名为“mess”。严肃地说,我不认为这是个好主意——在这种情况下我会使用嵌套类型。然后仍然很容易预测它在哪个源文件中。不过,我不认为这种方法有一个官方术语。

至于这是否会在不同的实现之间发生变化-我非常怀疑,但如果你一开始就避免这样做,你就永远不需要关心:)

不。你不能。但在Scala中这是非常可能的:

class Foo {val bar = "a"}
class Bar {val foo = "b"}

是的,你可以,在一个外部公共类上使用公共静态成员,就像这样:

public class Foo {

    public static class FooChild extends Z {
        String foo;
    }

    public static class ZeeChild extends Z {

    }

}

和另一个文件引用上述:

public class Bar {

    public static void main(String[] args){

        Foo.FooChild f = new Foo.FooChild();
        System.out.println(f);

    }
}

把它们放在同一个文件夹里。编译:

javac folder/*.java

并运行:

 java -cp folder Bar

我相信您可以将PrivateImpl定义为:一个非公共顶级类。您还可以声明非公共顶级接口。

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

至于不同版本之间的行为变化,有关于在1.2.2中“完美工作”的讨论。但是在sun的论坛:Java编译器1.4中停止工作-无法在文件中声明非公共顶级类。