《Effective Java》第4条:通过私有构造器强化不可实例化的能力

Posted by 代码无止境 on 2019-05-15

在实际的搬砖过程中,我们经常会写一些方便我们工作的工具类,一般来讲这类工具类是不希望被实例化的,因为实例对他们来讲没有任何的意义,毕竟它们不存储任何的数据。

不提供构造器

这应该是我们编写工具类的时候最常见的了,因为不需要实例化,所以我们一般都懒得去编写构造方法,但是我们忽略了编译器会为其提供一个默认的无参构造器,对于用户而言这个构造器和其他构造器没有任何区别。而且我们会发现在实际编码中我们有时候会无意识地实例化这些类。造成了资源的浪费。

通过抽象类来强制该类不可被实例化

或许我们会想到通过抽象类来强制这种工具类不被实例化,但是这是行不通的。因为该类可以被子类化,并且该类的子类可以被实例化,这样做还可能会误导用户,以为这种类是专门为继承而设计的。

私有化构造器

Java编译器只有当类不包含显式构造器的时候才会生成缺省构造器,所以我们只需要让这个类包含一个私有的显式构造器,它就不能被实例化了。

1
2
3
4
5
6
7
8
9
public class Example {

public static void test() {}

public static void test2() {}

private Example() {
}
}

看过上一条的同学应该知道,我们可以通过反射来强制调用私有构造器进而获得该类的实例,所以还需要改进一下。

1
2
3
4
5
6
7
8
9
10
public class Example {

public static void test() {}

public static void test2() {}

private Example() {
throw new AssertionError();
}
}

虽然一般来讲,AssertionError并不是必须的,但是这样可以避免我们不小心在类内部调用构造器也可以防止用户通过反射来获取新实例。

ps:“学习不止,码不停蹄”,如果你喜欢我的文章,就关注我吧。

扫码关注“代码无止境”