《Effective Java》学习笔记4 Enforce noninstantiability with a private constructor

版权声明:欢迎转载,但麻烦注明出处 https://blog.csdn.net/q2878948/article/details/81325581

本栏是博主根据如题教材进行Java进阶时所记的笔记,包括对原著的概括、理解,教材代码的报错和运行情况。十分建议看过原著遇到费解地方再来参考或与博主讨论。致敬作者Joshua Bloch跟以杨春花为首的译者团队。

 通过私有构造器强化不可实例化的能力 

很多情况下我们需要整个工具类出来以方便我们编程,比如Android中,为了防止使用Toast忘记show()一下,会把完整的Toast.makeText().show();放在工具类里面。

它们可以将相关联的方法、变量、数组归在一起;而对某些继承了一些接口的对象,可以根据{@link java.util.Collections}的方式,对这些静态方法分组,比如工厂方法等。(在Java8中,甚至可以直接把这些作为默认实现方法放在Interface定义的地方)

如果不希望被继承和修改,可以将这样的工具类设置为final类型。

这种工具类全都是静态成员变量跟成员方法,完全不需要实例化,但实际上,在缺少显式构造函数时,编译器总会偷偷地、自动地提供一个公有、无参、缺省的构造函数,而又没有跟普通构造函数间显著的区别,导致被无意识地实例化。

虽然改成抽象类可以防止实例化,但问题是抽象类可以通过子类实例化的,这也也会误导用户,让使用者感觉“是不是专门设计出来被继承的?”。因此,比较好的解决方法是将构造方法设置成私有,并添加注释说明,这个私有构造方法是因为该类不需要实例化而设置的。

这种方式也有一丢丢副作用,就是使一个类不能够被子类化。因为所有构造器都必须显式或隐式地调用超类的构造方法,在这种情况下,子类就没有可以访问的超类构造方法调用了。

另:这种类只起到辅助作用,而不应该喧宾夺主,把面向对象编程掰弯成面向过程编程

public class UtilityClass {

    /**
     * Suppress default constructor for noninstantiability
     */
    private UtilityClass(){
        //防止在本类内部不小心实例化掉,以确保任何时候都不会被实例化
        throw new AssertionError();
    }

    public static void staticMethod1(){
        //do sth
    }
}

全代码git地址:点我点我

猜你喜欢

转载自blog.csdn.net/q2878948/article/details/81325581