传统的两私有一公开(私有构造方法、私有静态实例(懒实例化/直接实例化)、公开的静态获取方法)涉及线程安全问题(即使有多重检查锁也可以通过反射破坏单例),

目前最为安全的实现单例的方法是通过内部静态enum的方法来实现,因为JVM会保证enum不能被反射并且构造器方法只执行一次。

实现方法如下:

  1. /**
  2. * 使用枚举的单例模式
  3. *
  4. * @author yzl
  5. * @see [相关类/方法](可选)
  6. * @since [产品/模块版本] (可选)
  7. */
  8. public class EnumSingleton{
  9. private EnumSingleton(){}
  10. public static EnumSingleton getInstance(){
  11. return Singleton.INSTANCE.getInstance();
  12. }
  13.  
  14. private static enum Singleton{
  15. INSTANCE;
  16.  
  17. private EnumSingleton singleton;
  18. //JVM会保证此方法绝对只调用一次
  19. private Singleton(){
  20. singleton = new EnumSingleton();
  21. }
  22. public EnumSingleton getInstance(){
  23. return singleton;
  24. }
  25. }
  26. }

测试方法:

  1. public static void main(String[] args) {
  2. EnumSingleton obj1 = EnumSingleton.getInstance();
  3. EnumSingleton obj2 = EnumSingleton.getInstance();
  4. //输出结果:obj1==obj2?true
  5. System.out.println("obj1==obj2?" + (obj1==obj2));
  6. }

扩展应用,观察下面的例子

  1. public class Test{
  2. //初始化一些东西
  3. static{
  4.  
  5. }
  6. }

这是一个很常见的类内部的静态资源初始化的写法(其实也就是单例的另外一种表现-只执行一次),但是将代码都写在static块下会看起来很不优雅,可以利用上面的enum单例模式来进行初始化操作。

见例子:

  1. import java.util.ArrayList;
  2. import java.util.List;
  3.  
  4. /**
  5. * 初始化的优雅实现
  6. * 可以在static处调用,
  7. * 也可以在普通方法里调用,都保证只初始化一次
  8. *
  9. * 当然将enum块的代码直接放到StaticInitTest类的private static 方法里做也是可以的
  10. *
  11. * @author yzl
  12. * @see [相关类/方法](可选)
  13. * @since [产品/模块版本] (可选)
  14. */
  15. public class StaticInitTest {
  16. private static List<Integer> dataList = null;
  17.  
  18. static{
  19. dataList = Singleton.INSTANCE.init();
  20. }
  21.  
  22. /**
  23. *
  24. * 单例模式来填充数据
  25. *
  26. * @author yzl
  27. * @see [相关类/方法](可选)
  28. * @since [产品/模块版本] (可选)
  29. */
  30. private static enum Singleton {
  31. INSTANCE;
  32. private List<Integer> list;
  33.  
  34. private Singleton(){
  35. fillData();
  36. }
  37. /**
  38. *
  39. * 初始化数据
  40. *
  41. * @see [相关类/方法](可选)
  42. * @since [产品/模块版本](可选)
  43. */
  44. private void fillData(){
  45. list = new ArrayList<Integer>(5);
  46. for(int i =1; i<6; i++){
  47. list.add(i);
  48. }
  49. }
  50.  
  51. /**
  52. *
  53. * 初始化的入口
  54. *
  55. * @see [相关类/方法](可选)
  56. * @since [产品/模块版本](可选)
  57. */
  58. public List<Integer> init(){
  59. return list;
  60. }
  61. }
  62. }

java单例之enum实现方式的更多相关文章

  1. JAVA单例实现方式(常用)

    JAVA单例实现方式(常用) public class Singleton { // Q1:为什么要使用volatile关键字? private volatile static Singleton u ...

  2. java单例的几种实现方法

    java单例的几种实现方法: 方式1: public class Something { private Something() {} private static class LazyHolder ...

  3. java单例-积木系列

    一步步知识点归纳吧,把以前似懂非懂,了解表面,知道点不知道面的知识归一下档.   懒汉式单例: 私有化构造函数,阻止外界实例话对象,调用getInstance静态方法,判断是否已经实例化. 为什么是懒 ...

  4. java单例五种实现模式梳理

    java单例五种实现模式 饿汉式(线程安全,调用效率高,但是不能延时加载) 一上来就把单例对象创建出来了,要用的时候直接返回即可,这种可以说是单例模式中最简单的一种实现方式.但是问题也比较明显.单例在 ...

  5. Java单例类的简单实现

    对于java新手来说,单例类给我的印象挺深,之前一道web后台笔试题就是写单例类.*.*可惜当时不了解. 在大部分时候,我们将类的构造器定义成public访问权限,允许任何类自由创建该类的对象.但在某 ...

  6. 【Java学习笔记之三十】详解Java单例(Singleton)模式

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  7. 熟悉的味道——从Java单例写到C++单例

    设计模式中,单例模式是常见的一种.单例模式需要满足以下两个条件: 保证一个类只能创建一个示例: 提供对该实例的全局访问点. 关于单例最经典的问题就是DCL(Double-Checked Lock),今 ...

  8. Java单例设计模式的实现

    1. 单例设计模式的定义 单例设计模式确保类只有一个实例对象,类本身负责创建自己的对象并向整个系统提供这个实例.在访问这个对象的时候,访问者可以直接获取到这个唯一对象而不必由访问者进行实例化. 单例设 ...

  9. java单例类/

    java单例类  一个类只能创建一个实例,那么这个类就是一个单例类 可以重写toString方法 输出想要输出的内容 可以重写equcal来比较想要比较的内容是否相等 对于final修饰的成员变量 一 ...

随机推荐

  1. ElasticSearch介绍 【未完成】

    ElasticSearch应用于搜索是一个不错的选择,虽有Lucene,但ELK的搜索方便. http://joelabrahamsson.com/elasticsearch-101/ 一.下载 ht ...

  2. 老调重弹:JDBC系列之<驱动加载原理全面解析) ----转

      最近在研究Mybatis框架,由于该框架基于JDBC,想要很好地理解和学习Mybatis,必须要对JDBC有较深入的了解.所以便把JDBC 这个东东翻出来,好好总结一番,作为自己的笔记,也是给读者 ...

  3. (转)C语言union(联合体 共用体)

    一直以来,union都是个很少用到的东西,对于这些不常用的结构往往记不住.这次看书又看到了,还是学习一下吧.一般在Windows API的一些数据结构中才能看到这个union,其实并不复杂.本质上来说 ...

  4. [leetcode 23]Merge k Sorted Lists

    1 题目 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexi ...

  5. 打印出所有的 "水仙花数 ",所谓 "水仙花数 "是指一个三位数 其各位数字立方和等于该数本身。 例如:153是一个 "水仙花数 " 因为153=1*1*1+5*5*5+3*3*3

    for (int i = 100; i <= 999; i++) { int geWei, shiWei, baiWei; baiWei = i / 100; shiWei = (i - bai ...

  6. 【原创】“借贷宝”砸钱,邀请码 GZZKZK2 (注册成功每人可得20现金,可直接提现)。。。而这只是开始

    作为IT/互联网资深码农的我,从专业技术角度剖析其流程,确认其各个环节控制严格,无欺诈嫌疑, 最佳运气邀请码 : GZZKZK2, 你在注册时值得拥有, 无邀请码无奖励, 亲一定要记住.对 APP操作 ...

  7. Dynamic CRM 2013学习笔记(五)禁止修改、删除审批通过后的单据

    审批通过后的单据,一般要对其进行控制,不能修改,不能添加,删除等,下面分别介绍下如何实现: 一. 禁止修改: 1. 主表控制,如果页面上审批状态为审批中或审批通过,就把整个页面都disable掉 1: ...

  8. 微软BI 之SSIS 系列 - MVP 们也不解的 Scrip Task 脚本任务中的一个 Bug

    开篇介绍 前些天自己在整理 SSIS 2012 资料的时候发现了一个功能设计上的疑似Bug,在 Script Task 中是可以给只读列表中的变量赋值.我记得以前在 2008 的版本中为了弄明白这个配 ...

  9. jQuery Ztree基本用法

    1.首先在页面上有<ul/>标签 <ul id="tree" class="ztree"></ul> 2.定义ztree的配 ...

  10. maven nexus 3 third party 构件上传

    mvn -e deploy:deploy-file -DgroupId=com.oracle -DartifactId=JDBCDriver -Dversion=12.0.1 -Dpackaging= ...