单例(singleton)就是一个只实例化一次的类。使类成为单例可能会使它的测试变得困难,因为除非它实现了作为其类型的接口,否则不可能用模拟实现来代替这个单例。下面是几种实现单例的方法:
// Singleton with public final field
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
public void leaveTheBuilding() { ... }
}
私有构造器只会被调用一次来初始化用 public static final
修饰的属性 INSTANCE
。因为没有 public
和 protected
的构造器,这里只会存在一个 Elvis 实例。
该方法的优点:
// Singleton with static factory
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
public static Elvis getInstance() { return INSTANCE; }
public void leaveTheBuilding() { ... }
}
所有对 Elvis.getInstance
的调用都返回相同的对象引用,并且不会创建其他的Elvis实例。
该方法的优点:
Elvis::instance
等同于 Supplier<Elvis>
。// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
这个方法与 public field 方法相似,但是更加简洁。这个方法看起来有一点不自然,但它通常是实现单例的最好方法。
注意:如果单例必须继承 Enum
以外的父类(尽管可以声明一个 Enum
来实现接口),那么就不能使用这种方法。
Effective Java 第三版读书笔记——条款3:使用私有构造器或枚举类型来强制实现 singleton 属性
原文:https://www.cnblogs.com/LeeFire/p/9921829.html