有效 Java:使构造函数私有或包私有

Effective Java: Make constructors private or package-private

Effective Java 第 4 章给出了以下示例:

public class Complex { 
    private final double re; 
    private final double im;

    private Complex(double re, double im) {
        this.re = re;
        this.im = im;
    }

    public static Complex valueOf(double re, double im) {
        return new Complex(re, im);
    }
    ... // Remainder unchanged
} 

[...] It is the most flexible because it allows the use of multiple package-private implementation classes. To its clients that reside outside its package, the immutable class is effectively final because it is impossible to extend a class that comes from another package and that lacks a public or protected constructor.

我知道 class 实际上是 final,

但是不声明它有什么实际好处吗final

当 class 不支持扩展时省略此关键字似乎不太清楚地传达 API 的用途。或者 final 只是被遗漏在这里以显示 reader 不可扩展的、非最终的 classes 是可能的?

这是优势: “...它允许使用多个包私有实现 classes”

如果它是最终的,扩展将是不可能的(无论是在包内还是包外)。通过这种方式,您可以在扩展 Complex 的包内创建另一个 class(前提是构造函数是包私有的)。

主要的好处是限制了继承的范围。声明它 final 将使其处处密封;然而,有时作为 class 的作者,您希望在同一个包或 class 文件中继承 class,但您不希望其他人也这样做。这就是这个技巧的作用。

改一个开放继承(常用API)的class简直是噩梦。如果能限制继承的范围,那么就变成了一个简单的重构工作。