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

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

实现方法如下:

/**
* 使用枚举的单例模式
*
* @author yzl
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class EnumSingleton{
private EnumSingleton(){}
public static EnumSingleton getInstance(){
return Singleton.INSTANCE.getInstance();
} private static enum Singleton{
INSTANCE; private EnumSingleton singleton;
//JVM会保证此方法绝对只调用一次
private Singleton(){
singleton = new EnumSingleton();
}
public EnumSingleton getInstance(){
return singleton;
}
}
}

测试方法:

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

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

public class Test{
//初始化一些东西
static{ }
}

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

见例子:

import java.util.ArrayList;
import java.util.List; /**
* 初始化的优雅实现
* 可以在static处调用,
* 也可以在普通方法里调用,都保证只初始化一次
*
* 当然将enum块的代码直接放到StaticInitTest类的private static 方法里做也是可以的
*
* @author yzl
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class StaticInitTest {
private static List<Integer> dataList = null; static{
dataList = Singleton.INSTANCE.init();
} /**
*
* 单例模式来填充数据
*
* @author yzl
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
private static enum Singleton {
INSTANCE;
private List<Integer> list; private Singleton(){
fillData();
}
/**
*
* 初始化数据
*
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
private void fillData(){
list = new ArrayList<Integer>(5);
for(int i =1; i<6; i++){
list.add(i);
}
} /**
*
* 初始化的入口
*
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public List<Integer> init(){
return list;
}
}
}

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. Troubleshoot Refused VNC Connection in CentOS 7

    Troubleshoot Refused VNC Connection in CentOS 7 Posted on March 15, 2015 by Istvan Szarka — 2 Commen ...

  2. 《Linux内核设计与实现》读书笔记(十三)- 虚拟文件系统

    虚拟文件系统(VFS)是linux内核和具体I/O设备之间的封装的一层共通访问接口,通过这层接口,linux内核可以以同一的方式访问各种I/O设备. 虚拟文件系统本身是linux内核的一部分,是纯软件 ...

  3. PropertyChangedCallback 只触发了一次?

    在自定义的用户控件中,添加一个依赖属性,如下: public static readonly DependencyProperty ItemsSourceProperty = DependencyPr ...

  4. C#函数式编程之部分应用

    何谓函数式编程 相信大家在实际的开发中,很多情况下完成一个功能都需要借助多个类,那么我们这里的基本单元就是类.而函数式编程则更加细化,致使我们解决一个功能的基本单元是函数,而不是类,每个功能都是由多个 ...

  5. uv纹理坐标设定与贴图规则

    1.什么是UV?   对于三维模型,有两个最重要的坐标系统,一是顶点的位置(X,Y,Z)坐标,另一个就是UV坐标.什么是UV?简单的说,就是贴图影射到模型表面的依据. 完整的说,其实应该是UVW(因为 ...

  6. JSP的那些事儿(2)---- DWR2.0 的配置和使用

    JSP的那些事儿(2)----DWR2.0 的配置和使用 分类: Web开发 JAVA 2009-04-23 15:43 999人阅读 评论(0) 收藏 举报 jspdwrjavascriptserv ...

  7. [ACM_搜索] ZOJ 1103 || POJ 2415 Hike on a Graph (带条件移动3盘子到同一位置的最少步数 广搜)

    Description "Hike on a Graph" is a game that is played on a board on which an undirected g ...

  8. [ucgui] 彩色条函数

    /* 颜色条 */ void ShowColorBar(void) { , y0 = , yStep = , i; int NumColors = LCD_GetDevCap(LCD_DEVCAP_N ...

  9. shiny server SparkR web展示界面(二)

    1.  需要先在Mac OS中安装好R,Rstudio中,这个比较简单,掠过 2. 下载编译好的spark(spark-2.0.0-bin-hadoop2.6.tgz)可以在Spark官网下载到你所需 ...

  10. XML的简单学习

    推荐入门级学习XML网址W3c     http://www.w3school.com.cn/xml/xml_intro.asp 1: XML 指可扩展标记语言    XML 被设计用来传输和存储数据 ...