只包含静态方法和静态域的类名声很不好,因为有些人用他们来用面向对象的语言来实现面向过程的程序,尽管如此,他们还是有很多用处的。比如说可以用这种类来组织某种基本类型的相关方法(java.lang.Math),也可以通过java.util.Collections方式把实现特定接口的对象上的静态方法组织起来,最后还能利用这种类把final类上的方法组织起来,以取代扩展该类的做法。
这种工具类的实例化是没有任何用处的,但是需要注意到的是在不提供构造函数的时候,编译器会自动提供一个默认的构造器。这会造成意识的实例化。一种补救方法是企图将类做成抽象类来阻止实例化,但是这种方法并不可靠,因为抽象类可以被继承,而它的子类是可以实例化的,这样甚至会误导用户以为这个类就是做出来让用户来继承使用的。另一种方法简单而且可靠,通过显示的提供一个私有的构造函数来阻止实例化。例如
// Noninstantiable utility class
public class UtilityClass {
// Suppress default constructor for noninstantiability
private UtilityClass() {
throw new AssertionError();
}
}
因为显示的提供了一个私有的构造器,因此不可以在类的外部进行访问,同时因为没有提供任何实例,因此也无法通过反射机制来访问,抛出异常不是必须的,但是它可以在不小心在类内部调用构造器的时候给我们提示,因为这种做法好像是在告诉用户“这个构造器就是来通知你们不能构造类实例的”,这种做法有些违反常理,因此最好加上一条注释。
这种习惯用法也有副作用,它使得一个类完全不能够子类化(因为子类中无法调用父类中的构造方法)。