单例

题目

设计一个类,我们只能生成该类的一个实例

解题思路

  • 线程安全
  • 延迟加载
  • 序列化与反序列化安全
  1. /**
  2. * 需要额外的工作(Serializable、transient、readResolve())来实现序列化,否则每次反序列化一个序列化的对象实例时都会创建一个新的实例。
  3. * <p>
  4. * 可能会有人使用反射强行调用我们的私有构造器(如果要避免这种情况,可以修改构造器,让它在创建第二个实例的时候抛异常)。
  5. *
  6. * @author haoyang.shi
  7. */
  8. public class Singleton {
  9. private Singleton() {
  10. }
  11. public static Singleton getInstance() {
  12. return Holder.instance;
  13. }
  14. private static final class Holder {
  15. private static Singleton instance = new Singleton();
  16. }
  17. }
  18. /**
  19. * 使用枚举除了线程安全和防止反射强行调用构造器之外,还提供了自动序列化机制,防止反序列化的时候创建新的对象。
  20. * <p>
  21. * 因此,Effective Java推荐尽可能地使用枚举来实现单例。
  22. */
  23. enum SingletonEnum {
  24. INSTANCE;
  25. private String name;
  26. public String getName() {
  27. return name;
  28. }
  29. public void setName(String name) {
  30. this.name = name;
  31. }
  32. }