资讯专栏INFORMATION COLUMN

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

bergwhite / 2248人阅读

摘要:企图通过将该类做成抽象类来强制该类不可被实例化,这是行不通的。这种习惯用法有点违背直觉,好像构造器就是专门设计成不能被调用一样。

  有时候你会想要编写一个只包含一组静态方法和静态字段的类。这种类名声很不好,因为有些人为了避免使用面向对象的思维方式而滥用这样的类(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 class
public class UtilityClass {
    // Suppress default constructor for noninstantiability
    private UtilityClass(( {
        throw new AssertionError();
    }
    ... // Remainder omitted
}

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

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73937.html

相关文章

  • 二章 创建和销毁对象

    摘要:一个类可以提供一个公共静态工厂方法,它仅仅是一第项遇到多个构造器参数时要考虑使用构建器静态工厂和构造器有个共同的局限性他们都不能很好地扩展到大量的可选参数。   本章涉及创建和销毁对象,包括何时以及如何创建它们,何时以及如何避免创建它们,如何确保它们被及时销毁,以及如何管理在销毁之前必须进行的清理操作。 第1项:用静态工厂方法代替构造器   类允许客户端获取实例的传统方法是提供公共构造...

    Jeffrrey 评论0 收藏0
  • Effective Java 3rd.Edition 翻译

    摘要:推荐序前言致谢第一章引言第二章创建和销毁对象第项用静态工厂方法代替构造器第项遇到多个构造器参数时要考虑使用构建器第项用私有构造器或者枚举类型强化属性第项通过私有构造器强化不可实例化的能力第项优先考虑依赖注入来引用资源第项避免创建不必要的对象 推荐序 前言 致谢 第一章 引言 第二章 创建和销毁对象 第1项:用静态工厂方法代替构造器 第2项:遇到多个构造器参数时要考虑使用构建器 第...

    KoreyLee 评论0 收藏0
  • Effective Java 三版 全文翻译

    摘要:本章中的大部分内容适用于构造函数和方法。第项其他方法优先于序列化第项谨慎地实现接口第项考虑使用自定义的序列化形式第项保护性地编写方法第项对于实例控制,枚举类型优先于第项考虑用序列化代理代替序列化实例附录与第版中项目的对应关系参考文献 effective-java-third-edition 介绍 Effective Java 第三版全文翻译,纯属个人业余翻译,不合理的地方,望指正,感激...

    galois 评论0 收藏0
  • 3:用私有造器或者枚举类型强化Singleton属性

    摘要:两者都基于保持构造函数私有并导出公共静态成员以提供对唯一实例的访问。在一种方法中,该成员是字段私有构造器只调用一次,用来初始化静态变量。由于缺少或者属性的构造器,这就保证了的全局一致性一旦类被实例化,只会存在一个实例,不多也不少。   Singleton指仅仅被实例化一次的类 [Gamma95]。Singleton通常代表无状态的对象,例如函数(第24项)或者本质上唯一的系统组件。使类...

    codeGoogle 评论0 收藏0
  • 《Effective Java》学习笔记 二章 创建和销毁对象

    摘要:第二章创建和销毁对象何时以及如何创建对象,何时以及如何避免创建对象,如何确保他们能够适时地销毁,以及如何管理对象销毁之前必须进行的各种清理动作。表示工厂方法所返回的对象类型。 第二章 创建和销毁对象 何时以及如何创建对象,何时以及如何避免创建对象,如何确保他们能够适时地销毁,以及如何管理对象销毁之前必须进行的各种清理动作。 1 考虑用静态工厂方法代替构造器 一般在某处获取一个类的实例最...

    tinylcy 评论0 收藏0

发表评论

0条评论

bergwhite

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<