Effective Java 2.0_中文版_Item 4

作者: SnailTyan | 来源:发表于2016-10-15 22:49 被阅读52次

    文章作者:Tyan
    博客:noahsnail.com  |  CSDN  |  简书

    Item 4: 用私有构造函数强制不能实例化

    有时你会想写一个只包含一组静态方法和静态变量的类。这种类的名声很不好,因为有些人滥用它们来避免思考如何面向对象,但它们确实是有用的。它们可以用来以java.lang.Mathjava.util.Arrays的方式来组织与基本类型或数组相关的方法。它们也可以用来以java.util.Collections的方式来组织实现特定接口对象的静态方法,包括工厂方法(Item 1)。最后,它们可以用来组织一个fianl类的方法,从而代替扩展这个类。

    这种工具类被设计成不能实例化:它的实例是没有意义的。然而,在缺少显式构造函数的情况下,编译器会提供一个公有的无参构造默认函数。对用户而言,这个构造函数与其它的构造函数没有任何差别。在发布的APIs中看到无意义的可实例化类是很罕见的。

    企图通过声明一个类为抽象类来强制类不能被实例化是行不通的。这个类可以被子类化,子类可以被实例化。而且,它会使用户误认为这个类是为继承而设计的(Item 17)。然而有一些简单的习惯用法可以确保类不能被实例化。如果一个类没有显式的构造函数,会产生默认的构造函数,因此,一个含有私有构造函数的类不能被实例化:

    // Noninstantiable utility class
    public class UtilityClass {
        // Suppress default constructor for noninstantiability
        private UtilityClass() {
            throw new AssertionError();
        }
        ...  // Remainder omitted
    }
    

    因为显式构造函数是私有的,因此类的外部不能访问构造函数。AssertionError不是必须的,但它可以避免类内部无意的调用构造函数。这种习惯用法有点违背直觉,似乎构造函数的提供就是为了它不能被调用一样。因此明智的做法是在类中加上注释,像上面的例子一样。

    这种习惯用法的一个副作用就是阻止了类的子类化。子类的所有的构造函数必须调用父类的构造函数,无论是显式的或隐式的,但这种情况下子类不能调用父类构造函数。

    相关文章

      网友评论

        本文标题:Effective Java 2.0_中文版_Item 4

        本文链接:https://www.haomeiwen.com/subject/kksoyttx.html