您的位置: 首页 > 技术专栏

Java高效编程:通过私有构造器强化不可实例化的能力

来源:  |  发布时间:2021-08-24  |  浏览量:85

有时候你会想要编写一个只包含一组静态方法和静态字段的类。这种类名声很不好,因为有些人为了避免使用面向对象的思维方式而滥用这样的类(some people abuse them to avoid thinking in terms of objects),但是他们确实有它们特有的用处。我们可以使用这种类,以java.lang.Math或者java.util.Arrays的方式对原始值或数组的相关方法组织起来。它们还可以用于以java.util.Collections的方式,把实现特定接口的对象上的静态方法(包括工厂:第 1 项)组织起来。(从 Java 8 开始,你也可以将这些方法放在接口中,假设它是你自己修改的)。最后,这些类可以用于将final类的方法组织起来,通过这种方式用来取代扩展该类的做法。

  这种工具类不希望被实例化,实例化对它没有任何意义。然而,在没有显式构造函数的情况下,编译器会默认提供一个公共的、无参的默认构造函数。对于用户而言,这个构造器与其他构造器没有任何区别。在已发行的 API 中常常可以看到一些被无意识地实例化的类。

  企图通过将该类做成抽象类来强制该类不可被实例化,这是行不通的。该类可以被子类化,并且该子类也可以被实例化。这样做甚至会误导用户,以为这种类是专门为了继承而设计的(第 19 项)。然而,有一些简单的习惯用法可以确保类不可被实例化。由于只有当类不包含显示的构造器时,编译器才会生成缺省的构造器,因此我们只要让这个类包含私有构造器,他就不能被实例化了:

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

  因为显示构造函数是私有的,所以它在类外是不可访问的,AssertionError不是必需的,但是它可以避免不小心在类的内部调用构造器。它保证该类在任何情况下都不会实例化。这种习惯用法有点违背直觉,好像构造器就是专门设计成不能被调用一样。因此明智的做法就是在代码中增加一条注释,如上所示。

  这种习惯用法也有副作用,它使得一个类不能拥有子类。因为子类的所有构造函数都必须显示或者隐式地调用父类的构造函数,在这种情形下,子类就没有可用的并且可以访问的父类构造器了。


相关新闻

24小时报名热线

400-7777-699

报名热线:400-7777-699

微博

微信公众号

友情链接 :智原在线   美味学院   安徽新华电脑   安徽新华教育

华信智原(官网)|京ICP备09028087号-8|咨询热线:400-7777-699|地址:北京海淀区北三环中路44号院爱工场文化教育产业园|版权所有:北京华信智原教育技术有限公司
在线报名 学费详情 开班信息 职业护航 视频下载

小小华想和您聊一聊