创建销毁对象(第四条:使用私有的构造器来强制不可实例化)

有时候你可能回去写一种只包含一些静态方法或者静态成员参数的类。因为一些人为了避免就对象相关的一些考虑就滥用它们,所以这种类的名声不太好。但是它们确实是有用处的。照着java.lang.Math 或者 java.util.Arrays的样子,它们可以用来对操作基本类型的方法或者数组类型的方法去做分组。照着java.util.Collections的样子,对于实现了某些接口的对象而言,它们可以把静态方法还有一些工厂方法(Item 1)分组放在一起(就java 8而言,假设是要改你的东西的话,你也可以将这些方法放在接口里面)。最后,可以把这种把用于方法分组的类设置为final的,因为你不能把它们放在子类里面。

这种utility classes设计出来是不能去实例化的:这种实例是毫无意义的。在缺少显示声明构造器的情况下,编译器会提供一个默认的无参的构造方法。对用户而言,这种构造器跟其他构造器都是一样的。在发布出去的API中也是常常看到这种不小心实例化的类的。通过尝试将类设置为abstract不能强制不可实例化。类可以被继承,子类可以实例化。另外它会误导用户去认为这个类设计出来就是为了继承(Item 19)。有一种简单的做法来保证不可实例化。因为只要不声明显示的构造方法,默认的构造方法就产生了。所以可以通过包含私有的构造器来实现类的不可实例化:

// Noninstantiable utility class
public class UtilityClass {
    // Suppress default constructor fornoninstantiability
    private UtilityClass() {
        throw new AssertionError();
    }

    // Remainder omitted
}

因为声明的构造器是私有的,所以在类的外部它是不可访问的。AssertionError不是必须的,但是如果不小心在类的内部调用了构造方法,它还是可以提供不可实例化的保证的。它能够保证在任何情况下一个类都不能被实例化。这种做法还是稍稍有点违反直觉的,因为显示的声明构造器是为了不能调用构造器。因此想上面一样包含一个注释是很明智的。

还有引申的作用是,这种做法还能防止类被继承。所有的构造器都必须显示的或者隐示的调用父类的构造方法,然而子类并没有权限去调用父类的构造方法。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值