Effective Java 3rd 条目4 用私有构造子实现不可实例化

有时,你想编写一个仅仅是一组静态方法和静态域的类。这样的类有个坏名声,因为一些人滥用它们来避免用对象的方式来思考,但是它们确实有正当的用途。以java.lang.Math或者java.util.Arrays的方式,它们可以把在原始或者队列上相应的方法归类。以java.util.Collections的方式,它们也可以归类实现了某个接口的对象的静态方法(包括工厂)(条目1)。(就像在Java 8,你也可以把这样的方法放在接口中,假设接口是你可修改的。)最后,这样的类可以在final类中归类方法,因为你不能够把它们放到子类里面。

效用(utility)类是设计成不可以实例化:一个实例毫无意义。然而,缺少了显示的构造子,编译器提供了一个公开的无参数默认构造子(default constructor)。对一个用户来说,这个构造子和其他的构造子是不可分辨的。在发布的API中,看见意外的可实例化类不是不常见的。

类变为一个抽象类的方法实现不可实例化,这并不奏效。类可以子类化,子类可以实例化。再者,这误导用户认为这个类是为继承而设计(条目19)。然而,有一个简单的惯常方法来保证不可实例化。只要一个类没有显示的构造子,一个默认构造子就会产生,所以类可以通过包含私有构造子使得它不可实例化

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

因为显式构造子是私有的,在类的外面不能够获取。AssertionError严格来说是不必要的,但是它提供了一种保证,以防构造子在类内意外被调用。它保证了类在任何环境下都不可能被实例化。这个惯常用法是非常反直觉的,因为构造子是专门提供的,以便它不能够调用。所以,包涵一个如上所示的注释是明智的。

有个缺陷,这个惯常用法同时阻止了类的子类化。所有的构造子必须显式地或者隐式地调用超类的构造子,而且子类不可获取调用超类的构造子。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 33,052评论 18 399
  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 7,618评论 0 11
  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 11,948评论 0 62
  • 宝宝刚2个多月的时候,有一天晚上10点多,宝宝哄睡了一个多小时,但是她仍然没有睡着,反而一直在吧唧嘴巴,或者吃自己...
    江南咸鸭蛋阅读 5,040评论 0 0
  • 7月19日 星期三 暴热升级 不知是咖啡的原因还是心魔的作用,在床上辗转反侧五个小时,将自己的人生想了个透彻还...
    夏尔烟阅读 2,425评论 0 2

友情链接更多精彩内容