随着计算机革命发展,“不安全”的编程方式逐渐成为编程代价高昂的主因之一。初始化和清理(cleanup)是涉及安全的两个问题。
C++引入了构造器(constructor)的概念,这是一个创建对象时被自动调用的特殊方法,Java 也采用了构造器,并额外提供了“垃圾回收器”。
我们有可能需要编写一些工具类,它们只包含静态方法和静态域的类,而且这样的工具类(utility class)不希望被实例化,实例对它们没有任何意义。
由于工具类不希望被实例化,然而在缺少显式构造器的情况下,编译器会自动提供一个公有的、无参的缺省构造器(default constructor)。对于用户而言,这个构造器与其它的构造器没有区别。
企图通过将类做成抽象类来强制该类不可被实例化,这是行不通的:因为这个类可以被子类化,并且也可以被实例化。所以,这样做会误导用户,让使用者误以为是为了继承而设计的。
我们可以对工具类进行如下优化:
//不可实例化的工具类
public class UtinityClass {
//显式声明一个私有化的构造器,使得无法实例化该类
private UtinityClass() {
throw new AssertionError();
}
}
经过私有化构造器,外层实例化工具类的代码将会及时的发出错误提醒,从而达到不可实例化的目的(由于显式的构造器是私有的,所以不可以在该类的外部访问它):
通过私有化构造器,来强化某些类的不可实例化能力。这种习惯做法也有副作用,它使得一个类不能被子类化。
因为子类化,要求子类所有的构造器都必须显式或者隐式的调用超类(superclass)构造器,而经过私有化该类构造器,导致想要继承于它的子类没有可访问的超类构造器可调用了。