java单例之enum实现方式

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

目前最为安全的实现单例的方法是通过内部静态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;
        }
    }
}
时间: 2024-08-07 14:16:40

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

java单例设计模式八种方式

单例设计模式介绍 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法). 比如Hibernate的SessionFactory,它充当数据存储源的代理,并负责创建Session对象.SessionFactory并不是轻量级的,一般情况下,一个项目通常只需要一个SessionFactory就够,这是就会使用到单例模式. 单例设计模式八种方式 单例模式有八种方式: 饿汉式( ( 静态常 量) ) 饿汉式(静态

Java 单例

最近在网上看到一篇关于 Java 单例的创建问题,虽然是一个 Java 程序员,但是到现在还没有真正的深入了解到 Java 的原理和机制.所以每每看到这样能够"真正"接触 Java 的机会内心总是充满了欣喜.记录下,以后备用. 懒汉模式 public class Singlton{ private static Singleton instance; private Singlton(){} public static Singlton getInstance(){ if(instac

java单例-积木系列

一步步知识点归纳吧,把以前似懂非懂,了解表面,知道点不知道面的知识归一下档. 懒汉式单例: 私有化构造函数,阻止外界实例话对象,调用getInstance静态方法,判断是否已经实例化. 为什么是懒汉,因为它是属于延迟加载这个实例的,也就是说不用到的时候,不实例化对象的. public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInst

Java单例设计模式的实现

1. 单例设计模式的定义 单例设计模式确保类只有一个实例对象,类本身负责创建自己的对象并向整个系统提供这个实例.在访问这个对象的时候,访问者可以直接获取到这个唯一对象而不必由访问者进行实例化. 单例设计模式保证了全局对象的唯一性,在许多场景中都有应用.例如Windows中多个进程或线程同时操作一个文件的时候,所有的进程或线程对于同一个文件的处理必须通过唯一的实例来进行. 2. java单例设计模式的几种实现方式 单例设计的最大特点是类的构造函数是私有的,确保了只能由类本身创建对象,而访问者无法进

java单例类/

java单例类  一个类只能创建一个实例,那么这个类就是一个单例类 可以重写toString方法 输出想要输出的内容 可以重写equcal来比较想要比较的内容是否相等 对于final修饰的成员变量 一但有了初始值,就不能被重新赋值 static修饰的成员变量可以在静态代码块中 或申明该成员时指定初始值 实例成员可以在非静态代码块中,申明属性,或构造器中指定初始值 final修饰的变量必须要显示初始化 final修饰引用变量不能被重新赋值但是可以改变引用对象的内容分(只要地址值不变) final修

iOS中创建单例的两种方式

刚刚开始做iOS开发的时候,不知道怎么创建单例,在网上搜的也大多数都不太全,所以总结了一下创建单例的两种方式 首先在.h文件中声明类方法 1 +(instancetype)sharedUtils; 然后在.m文件中实现它,实现的方法有两种 第一种,在创建一个对象时先判断在程序中有没有创建过这个对象 1 static PublicUtils *DefaultManager = nil; 2 3 +(instancetype)sharedUtils 4 { 5 if (!DefaultManager

Java单例的实现

1.声明实例变量(静态) 2.私有化构造函数 3.创建获取实例的方法 public class Singleton{ //创建实例变量 private static Singleton singleton; //私有化构造函数 private Singleton(){ } //创建获取实例的方法 public static Singleton getInstance(){ if(singleton==null){ singleton=new Singleton(); } return singl

Java 单例总结

1:懒汉式,不保证线程安全 package com.yan.singleton; public class LazySingleton { private static final LazySingleton instance = null; private LazySingleton(){} public static LazySingleton getLazySingleton(){ if(null==instance){ return new LazySingleton(); } retu

Java 单例真的写对了么?

单例模式是最简单的设计模式,实现也非常“简单”.一直以为我写没有问题,直到被 Coverity 打脸. 1. 暴露问题 前段时间,有段代码被 Coverity 警告了,简化一下代码如下,为了方便后面分析,我在这里标上了一些序号: private static SettingsDbHelper sInst = null; public static SettingsDbHelper getInstance(Context context) { if (sInst == null) { // 1 s