私有构造函数使类不可实例化-第二章创建和销毁对象-Effective Java学习笔记03

文章内容来源于Joshua Bloch - Effective Java (3rd) - 2018.chm一书

第二章

创建和注销对象

Item 4不可实例的要有Private构造函数

Enforce noninstantiability with a private constructor

有时你会希望编写一个类只包含一组静态方法和静态字段

这样的类业内骂声一片,就object而言,因为有些人无脑滥用,但是它们确实有有效的用途

  • 它们可以对相关方法进行分组用基元值或数组,用java.lang.Math或者java.util.Arrays
  • 它们还可以用于对实现某些接口的对象的静态方法进行分组,用java.util.Collections文件
  • 再或者,这些类可以用于将方法分组到final类中,因为您不能将它们放在子类中
  • (Java8及之后,还可以将这些方法放在接口中,如果你修改这些方法)

这样的utility classes 类并不是被设计去实例的:一个这样的实例是没有意义的

但是,在没有explicit 构造函数的情况下,编译器提供了一个public、无参数的默认构造函数

对于用户来说,此构造函数与任何其他构造函数都没有区别

在已发布的API中无意看到可实例化类并不是不常见的

试图通过使类抽象来强制不可实例化是行不通的

类可以是子类,子类就可以实例化

此外,它误导用户认为类是为继承而设计的

然而,有一个简单的用法可以确保不可实例

只有类没有explicit构造函数时,才会生成默认构造函数,因此

可以通过包含私有构造函数使类不可实例化:

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

因为显式explicit 构造函数是私有的,所以在类之外是不可访问的

AssertionError这个错误并不是严格要求的,但它提供了一种保险方式,以防构造函数从类中意外调

它保证类在任何情况下都不会被实例化

这个习惯用法有点违反直觉,因为构造函数是明确提供的,还不能被调用

所以像上述例子,明智的做法是添加注释

作为一个副作用,这个习惯用法也防止类被子类化

(正常情况下)所有构造函数都必须调用父类构造函数,显式或隐式,(但本例)子类将没有可访问的父类构造函数可调用

猜你喜欢

转载自blog.csdn.net/weixin_43596589/article/details/112555408