使用private构造器 or 枚举的原生语言实现单例

简介: 相信接触过设计模式的同学都知道,单例的一种经典实现方式就是private的构造函数,但直到我看到这一章节内容的时候,才突然顿悟原来枚举类型也是可以强化单例属性的,自愧个人的融会贯通能力还有待加强。

相信接触过设计模式的同学都知道,单例的一种经典实现方式就是private的构造函数,但直到我看到这一章节内容的时候,才突然顿悟原来枚举类型也是可以强化单例属性的,自愧个人的融会贯通能力还有待加强。

实现单例方式一:


// Singleton with public final field
public class Elvis {
  public static final Elvis INSTANCE= new Elvis();
  private Elvis() { .. . }
}


这种实现方式有一个缺点就是可以借助反射机制里的AccessibleObject.setAccessible来强制修改构造函数成为public的

实现单例方式二:


// Singleton with static factory
public class Elvis {
private static final Elvis INSTANζE = new Elvis();
  private Elvis() { ... }
  public static Elvis getInstance() {return INSTANCE; }
}


在实际抉择中,如果用到了以下某种优势,则优先考虑第二种实现,否则考虑第一种单例实现:


可以很容易被修改成非单例的(修改getInstance的返回语句即可)

可以使用Elvis::instance语法


此外,为了防止每次序列化和反序列化都创建一个新实例而破坏了单例特性,需要在Elvis类中添加一个方法:


private Object readResolve () {
  return INSTANCE;
}


实现单例方式三:


这种方式也是我原先没有想到的,声明包含单个元素的枚举类型来实现:

public enum Elvis {
  INSTANCE;
  public void leaveTheBuilding() { .. . }
}


其中Elvis.INSTANCE可以获得单例,Elvis.INSTANCE.leaveTheBuilding();调方法。


这种方式也是作者极力推荐的一种方式,无偿地提供了序列化机制,绝对防止多次实例化。单元素的枚举类型经常成为实现Singleton的最佳方法。

相关文章
|
设计模式 Java
Java反射(Class、反射实例化、反射与单例、获取类结构)附带相关面试题
1.了解反射,2.Class类的三种实例化方法,3.反射机制与对象实例化,4.反射与单例设计模式,5.通过反射获取类结构的信息
303 0
|
3月前
|
算法 Java
12 Java常用类(一)(内部类+object类+包装类)
12 Java常用类(一)(内部类+object类+包装类)
37 5
|
5月前
|
Java
java反射-获取类的Class对象方式
java反射-获取类的Class对象方式
|
5月前
|
Java 编译器 数据处理
JavaSE——面相对象高级一(4/4)-继承相关的注意事项:权限修饰符、单继承、Object类、方法重写、子类访问成员的特点......
JavaSE——面相对象高级一(4/4)-继承相关的注意事项:权限修饰符、单继承、Object类、方法重写、子类访问成员的特点......
57 0
|
6月前
|
Java
Java提供了四种访问修饰符来控制类、变量、方法和构造器的访问级别
Java提供了四种访问修饰符来控制类、变量、方法和构造器的访问级别
61 1
|
6月前
|
存储 Java
Java的接口、类、属性、方法的修饰符使用总结
Java的接口、类、属性、方法的修饰符使用总结
373 0
|
druid Java 编译器
Java的第七篇文章——面向对象接口(包含了接口、static修饰符、final修饰符、main方法、内部类等知识点)
Java的第七篇文章——面向对象接口(包含了接口、static修饰符、final修饰符、main方法、内部类等知识点)
|
SQL 缓存 安全
Java枚举单例模式比DCL和静态单例要好?———反编译分析单例枚举类
枚举单例模式比DCL和静态单例模式要好?为什么好呢?本文带你一探究竟!
115 0
Java枚举单例模式比DCL和静态单例要好?———反编译分析单例枚举类
|
缓存 Dart 安全
Dart中的类——初始化列表、命名构造器、factory构造器、常量构造器、构造器私有化、get和set方法、枚举
Dart中的类——初始化列表、命名构造器、factory构造器、常量构造器、构造器私有化、get和set方法、枚举
|
Java
编写Java程序,创建一个数学工具类,将该类设计为final类,Final 修饰符的使用。
编写Java程序,创建一个数学工具类,将该类设计为final类,Final 修饰符的使用。
285 0
编写Java程序,创建一个数学工具类,将该类设计为final类,Final 修饰符的使用。