Effective.Java 读书笔记(4)非实例化
2017-02-19 本文已影响0人
Mezereon
4.Enforce noninstantiability with private constructor
大意为 使用private的构造方法来实现的非实例化
有时你想要编写一个类,这个类只是静态方法和静态域的组成,这样的一个类获得一个糟糕的名声因为一些人滥用他们为了避免对对象的术语进行思考,但是他们的确是有用的
他们可以被使用在原始的值或者数组上组合有关的方法,比如在java.lang.Math或者java.util.Arrays上的方式,他们也可以被用来组合静态方法,包括工厂方法,对于实现了一个特定接口的对象,比如在Collections上的方式,最后他们可以被用来在final类上组合方法而不用继承其他类。
这样的工具类不会被设计成可以被初始化的类,一个实例是没有意义的,显式的构造方法没有必要出现,然而,编译器提供了一个public,无参的默认的构造方法,对于用户来说,这个构造方法是和其他的构造方法是不可区分的,在公开的API中见到无意的可初始化类也是常事
为了非实例化,使一个类抽象并没有什么作用,这个类可以被子类化,并且子类可以被实例化,而且,它会误导用户去认为这个类是设计来继承的,那么如何实现非实例化呢,很简单,我们知道默认的构造方法只会在没有其他冲突的构造方法的情况下才会自动生成,所以一个类只需包括一个private的构造方法就可以实现非实例化
// Noninstantiable utility class
public class UtilityClass {
// Suppress default constructor for noninstantiability
private UtilityClass() {
throw new AssertionError();
}
... // Remainder omitted
}
因为这个构造方法是private的,所以在类的外部不可以被访问,AssertionError并不是严格需要的,但是它提供了构造器意外构造时的保险,它保证了这个类不会在任何情况下被实例化
另一方面,这个类也不可以被子类化。所有的构造方法必需调用父类的构造方法,显地式的或者隐式地调用,一个子类并没有父类可行的构造方法可以去调用