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

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

例如,PublicClass.java:

package com.example.multiple;

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

class PrivateImpl {
    int implementationData;
}

当前回答

仅供参考,如果你使用Java 11+,这条规则有一个例外:如果你直接运行你的Java文件(没有编译)。在这种模式下,每个文件对单个公共类没有限制。但是,带有main方法的类必须是文件中的第一个类。

其他回答

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

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

你想上多少课就可以上多少课

public class Fun {
    Fun() {
        System.out.println("Fun constructor");
    }
    void fun() {
        System.out.println("Fun mathod");
    }
    public static void main(String[] args) {
        Fun fu = new Fun();
        fu.fun();
        Fen fe = new Fen();
        fe.fen();
        Fin fi = new Fin();
        fi.fin();
        Fon fo = new Fon();
        fo.fon();
        Fan fa = new Fan();
        fa.fan();
        fa.run();
    }
}

class Fen {
    Fen() {
        System.out.println("fen construuctor");

    }
    void fen() {
        System.out.println("Fen method");
    }
}

class Fin {
    void fin() {
        System.out.println("Fin method");
    }
}

class Fon {
    void fon() {
        System.out.println("Fon method");
    } 
}

class Fan {
    void fan() {
        System.out.println("Fan method");
    }
    public void run() {
        System.out.println("run");
    }
}

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

多类单文件演示。

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

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

根据Effective Java第二版(第13项):

如果包私有顶级类(或接口)仅被 一个类,考虑将顶层类设置为私有嵌套类 唯一使用它的类(第22项)。这就减少了 从其包中的所有类到一个类的可访问性 它使用了它。但更重要的是降低可访问性 一个免费的公共类而不是包私有的顶级类: ……”

嵌套类可以是静态的,也可以是非静态的,这取决于成员类是否需要访问外围实例(第22项)。

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

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

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