JAVA源文件只包含一个顶层类

文章也上传到

github

(欢迎关注,欢迎大神提点。)


ITEM25 保持一个源文件只包含一个顶层类


虽然Java编译器允许你在一个源文件中定义多个顶层类,但是你这么做也没有任何好处,反而会有一些明显的坏处。主要的坏处是:可能会造成一个类有多种实现。最终使用哪一种实现依赖于源文件被添加到编译器的先后顺序。

举个实例,下面的源文件包含一个Main类,它引用了两个顶层类(Utensil和Dessert):


public class Main {
    public static void main(String[] args) {
        System.out.println(Utensil.NAME + Dessert.NAME);
    }
}

现在假设你是在一个文件Utensil.java中定义了这两个类:


class Utensil {
    static final String NAME = "pan";
}

class Dessert {
    static final String NAME = "cake";
}

很显然,程序会打印出pancake。

现在假设你无意间定义了另外一个源文件Dessert.java,里面也同时定义了这两个类:


class Utensil {
    static final String NAME = "pot";
}

class Dessert {
    static final String NAME = "pie";
}

此时, – 如果编译命令是:javac Utensil.java Dessert.java,编译就会失败,告诉你有同名的类(Utensil和Dessert)定义。 – 如果编译命令是javac Main.java Utensil.java,结果就是pancake; – 如果编译命令是javac Dessert.java Main.java,结果就是potpie; 也就是说结果依赖于哪个文件被编译了。

修复这个问题很简单,只需要将其中一个类分开到另一个文件即可。如果你真的需要将多个顶层类放到一起,可以参考(Item24)中的嵌套类。如果一个类从属于其他类,那就使他们成为静态的成员类,因为这样提高可读性并且可通过声明private降低可访问性。这里给个例子:

public class Test {

    public static void main(String[] args) {
        System.out.println(Utensil.NAME + Dessert.NAME);
    }

    private static class Utensil {
        static final String NAME = "pan";
    }

    private static class Dessert {
        static final String NAME = "cake";
    }
}

这一小节很简短,主旨是:永远不要把多个顶层类或者接口放到同一个源文件中。这反过来保证了编译生成的类文件以及生成的程序的行为与源文件传递给编译器的顺序无关。

发表评论

关闭菜单