[Effective Java] (04)通过私有构造器强化不可实例化的能力

编写只包含静态方法和静态域的类深受诟病,因为有些人在面向对象的语言中滥用这样的类来编写过程化的程序。但在创建工具类的时候,大部分是无需实例化的,并且实例化他们也没有意义,在这种情况下需要确保该类是不可实例化的。

存在问题:
在创建不可实例化的类时,虽然没有定义构造器,编译器会自动提供一个公有的、无参的缺省构造器(default constructor),客户端依然可以实例化它,并且可以继承该类并通过实例化子类来实现实例化;

定义私有构造器
public class ToolClass {
    //Supperss default constructor for noninstantiability
    private ToolClass() {
        throw new AssertionError();
    }
}
  • 添加了throw new AssertionError()避免了实例化ToolClass类;
  • 私有了无参构造器,这样客户端没有办法调用默认构造函数来实例化该类;也避免了继承的子类实例化的问题。

实例化如下类会报如下所示错误:

public class ToolClass {

    //Supperss default constructor for noninstantiability
    private ToolClass() {
        throw new AssertionError();
    }
    
    public static void main(String[] args) {
        ToolClass toolClass = new ToolClass();
    }
}

上述代码执行会报如下错误:

Exception in thread "main" java.lang.AssertionError
    at g.ToolClass.<init>(ToolClass.java:9)
    at g.ToolClass.main(ToolClass.java:13)

注:throw new AssertionError()不是必需的,但是它可以避免不小心在类的内部调用构造器。

在试图继承ToolClass时会报以下错误:

Implicit super constructor ToolClass() is not visible for default constructor. 
        Must define an explicit constructor