Java中如何实现单例模式?

2026-05-22 14:531阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1846个文字,预计阅读时间需要8分钟。

Java中如何实现单例模式?

前言本篇博客主要记录Java23种设计模式中的创建型模式中的单例模式。单例模式可分为两类:一种是饿汉式,一种是懒汉式。饿汉式的三种设计方式(静态变量方式、静态代码块方式和枚举方式)如下。

单例模式的饿汉式

1. 静态变量方式

javapublic class Singleton { private static final Singleton INSTANCE=new Singleton();

private Singleton() { // 构造器私有,防止外部直接创建对象 }

public static Singleton getInstance() { return INSTANCE; }}

2. 静态代码块方式

javapublic class Singleton { private static Singleton INSTANCE;

Java中如何实现单例模式?

private Singleton() { // 构造器私有,防止外部直接创建对象 }

static { INSTANCE=new Singleton(); }

public static Singleton getInstance() { return INSTANCE; }}

3. 枚举方式

javapublic enum Singleton { INSTANCE;

public void whateverMethod() { // 实例方法 }}

前言

本片博客主要记录Java23种设计模式中的创建型模式中的单例模式。单例模式可分为两类,一种是饿汉式,一种是懒汉式。饿汉式的三种设计方式(静态变量方式、静态代码块方式、枚举方式),懒汉式(单锁检查方式、双锁检查方式、静态内部类方式),以及破坏单例模式的两种方式:序列化反序列化,反射。
设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性

单例模式结构

私有的构造方法
私有的、静态的实例化变量应用
提供一个公有的、静态的获取类实例对象方法

单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。它提供了一种创建对象的最佳方式。

单例模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。

饿汉式 静态变量方式
  • 直接在创建对象时赋值

package hello; public class Hello { public static void main(String[] args) { //只能通过getSingleton方法获取,不能通过new方法创建 Singleton singleton = Singleton.getSingleton(); Singleton singleton11 = Singleton.getSingleton(); //通过hashCode查看是否是同一个对象 System.out.println(singleton.hashCode()); System.out.println(singleton11.hashCode()); } } class Singleton{ //私有构造方法,这样外界就不能创建了 private Singleton(){ } //自己创建一个对象 private static Singleton singleton = new Singleton(); //给外界提供一个方法用于访问 public static Singleton getSingleton(){ return singleton; } } 静态代码块方式

  • 在静态代码块里赋值

package hello; public class Hello { public static void main(String[] args) { //只能通过getSingleton方法获取,不能通过new方法创建 Singleton singleton = Singleton.getSingleton(); Singleton singleton11 = Singleton.getSingleton(); //通过hashCode查看是否是同一个对象 System.out.println(singleton.hashCode()); System.out.println(singleton11.hashCode()); } } class Singleton{ //私有构造方法,这样外界就不能创建了 private Singleton(){ } //自己创建一个对象,但是不实例 private static Singleton singleton; //通过静态代码块赋值 static { singleton = new Singleton(); } //给外界提供一个方法用于访问 public static Singleton getSingleton(){ return singleton; } } 枚举方式

由于上面检测代码相同,就不在这里重复复制了。
只需要把class Singleton改为下面就行了

enum Singleton{ SINGLETON; } 懒汉式 单锁检查模式

package hello; public class Hello { public static void main(String[] args) { Singleton singleton = Singleton.getSingleton(); Singleton singleton11 = Singleton.getSingleton(); //通过hashCode查看是否是同一个对象 System.out.println(singleton.hashCode()); System.out.println(singleton11.hashCode()); } } class Singleton{ //私有构造方法,这样外界就不能创建了 private Singleton(){ } //自己声明一个对象 private static Singleton singleton; //给外界提供一个方法用于访问 public static synchronized Singleton getSingleton(){ //判读singleton是否为null,如果是null就创建,否者直接返回 if (singleton == null){ singleton = new Singleton(); } return singleton; } } 双重检查锁模式

上面的验证都是一样的,这里只显示Singleton类就行

class Singleton{ //私有构造方法,这样外界就不能创建了 private Singleton(){ } //自己声明一个对象 private static volatile Singleton singleton; //给外界提供一个方法用于访问 public static synchronized Singleton getSingleton(){ //判读singleton是否为null,如果是null就创建,否者直接返回 if (singleton == null){ synchronized (Singleton.class){ if (singleton == null){ singleton = new Singleton(); } } } return singleton; } } 静态内部类实现

  • 静态内部类单例模式是一种优秀的单例模式,是比较常用的单例模式。在没有加任何锁时保证线程安全,并且没有任何性能影响和空间浪费。

  • 在加载Singleton时不会初始化singleton,只有第一次调用getSingleton()时。JVM加载SingletonHolder初始化singleton。

class Singleton{ //私有构造方法,这样外界就不能创建了 private Singleton(){ } //定义一个静态内部类 private static class SingletonHolder{ //只会初始化一次 private static final Singleton singleton= new Singleton(); } //给外界提供一个方法用于访问 public static synchronized Singleton getSingleton(){ return SingletonHolder.singleton; } } 破坏单例模式

  • 破坏单例模式的方式有两种一种是序列化反序列化,另一种是反射,这里我们指记录反射
  • 道高一尺,魔高一丈。有模式就会有破坏,有破坏还会有防破坏,但是还有反反破坏。这里面就多了。
通过反射破坏单例模式

package hello; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Hello { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //获取Singleton字节码对象 Class<Singleton> singletonClass = Singleton.class; //获取无参构造方法 Constructor<Singleton> declaredConstructor = singletonClass.getDeclaredConstructor(); //取消访问检查 declaredConstructor.setAccessible(true); //创建Singleton对象 Singleton singleton = (Singleton) declaredConstructor.newInstance(); Singleton singleton1 = (Singleton) declaredConstructor.newInstance(); //通过hashCode查看是否是同一个对象 System.out.println(singleton.hashCode()); System.out.println(singleton1.hashCode()); } } class Singleton{ //私有构造方法,这样外界就不能创建了 private Singleton(){ } //定义一个静态内部类 private static class SingletonHolder{ //只会初始化一次 private static final Singleton singleton= new Singleton(); } //给外界提供一个方法用于访问 public static synchronized Singleton getSingleton(){ return SingletonHolder.singleton; } } 单例模式优缺点

优点:

  • 单例模式在内存中只有一个实例,减少内存开支,特别是一个对象需要频繁地创建销毁时,而且创建或销毁时性能又无法优化,单例模式就非常明显了
  • 单例模式只生成一个实例,减少系统的性能开销
  • 单例模式可以避免对资源的多重占用
  • 单例模式可以在系统设置全局的访问点,优化和共享资源访问
    缺点:
  • 不适用于变化的对象
  • 由于单例模式没有抽象层,所以扩展困难
  • 单例类的职责过重,在一定程度上违背了“单一职责原则”
  • 单一职责原则:一个类,应该只有一个职责

本文共计1846个文字,预计阅读时间需要8分钟。

Java中如何实现单例模式?

前言本篇博客主要记录Java23种设计模式中的创建型模式中的单例模式。单例模式可分为两类:一种是饿汉式,一种是懒汉式。饿汉式的三种设计方式(静态变量方式、静态代码块方式和枚举方式)如下。

单例模式的饿汉式

1. 静态变量方式

javapublic class Singleton { private static final Singleton INSTANCE=new Singleton();

private Singleton() { // 构造器私有,防止外部直接创建对象 }

public static Singleton getInstance() { return INSTANCE; }}

2. 静态代码块方式

javapublic class Singleton { private static Singleton INSTANCE;

Java中如何实现单例模式?

private Singleton() { // 构造器私有,防止外部直接创建对象 }

static { INSTANCE=new Singleton(); }

public static Singleton getInstance() { return INSTANCE; }}

3. 枚举方式

javapublic enum Singleton { INSTANCE;

public void whateverMethod() { // 实例方法 }}

前言

本片博客主要记录Java23种设计模式中的创建型模式中的单例模式。单例模式可分为两类,一种是饿汉式,一种是懒汉式。饿汉式的三种设计方式(静态变量方式、静态代码块方式、枚举方式),懒汉式(单锁检查方式、双锁检查方式、静态内部类方式),以及破坏单例模式的两种方式:序列化反序列化,反射。
设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性

单例模式结构

私有的构造方法
私有的、静态的实例化变量应用
提供一个公有的、静态的获取类实例对象方法

单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。它提供了一种创建对象的最佳方式。

单例模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。

饿汉式 静态变量方式
  • 直接在创建对象时赋值

package hello; public class Hello { public static void main(String[] args) { //只能通过getSingleton方法获取,不能通过new方法创建 Singleton singleton = Singleton.getSingleton(); Singleton singleton11 = Singleton.getSingleton(); //通过hashCode查看是否是同一个对象 System.out.println(singleton.hashCode()); System.out.println(singleton11.hashCode()); } } class Singleton{ //私有构造方法,这样外界就不能创建了 private Singleton(){ } //自己创建一个对象 private static Singleton singleton = new Singleton(); //给外界提供一个方法用于访问 public static Singleton getSingleton(){ return singleton; } } 静态代码块方式

  • 在静态代码块里赋值

package hello; public class Hello { public static void main(String[] args) { //只能通过getSingleton方法获取,不能通过new方法创建 Singleton singleton = Singleton.getSingleton(); Singleton singleton11 = Singleton.getSingleton(); //通过hashCode查看是否是同一个对象 System.out.println(singleton.hashCode()); System.out.println(singleton11.hashCode()); } } class Singleton{ //私有构造方法,这样外界就不能创建了 private Singleton(){ } //自己创建一个对象,但是不实例 private static Singleton singleton; //通过静态代码块赋值 static { singleton = new Singleton(); } //给外界提供一个方法用于访问 public static Singleton getSingleton(){ return singleton; } } 枚举方式

由于上面检测代码相同,就不在这里重复复制了。
只需要把class Singleton改为下面就行了

enum Singleton{ SINGLETON; } 懒汉式 单锁检查模式

package hello; public class Hello { public static void main(String[] args) { Singleton singleton = Singleton.getSingleton(); Singleton singleton11 = Singleton.getSingleton(); //通过hashCode查看是否是同一个对象 System.out.println(singleton.hashCode()); System.out.println(singleton11.hashCode()); } } class Singleton{ //私有构造方法,这样外界就不能创建了 private Singleton(){ } //自己声明一个对象 private static Singleton singleton; //给外界提供一个方法用于访问 public static synchronized Singleton getSingleton(){ //判读singleton是否为null,如果是null就创建,否者直接返回 if (singleton == null){ singleton = new Singleton(); } return singleton; } } 双重检查锁模式

上面的验证都是一样的,这里只显示Singleton类就行

class Singleton{ //私有构造方法,这样外界就不能创建了 private Singleton(){ } //自己声明一个对象 private static volatile Singleton singleton; //给外界提供一个方法用于访问 public static synchronized Singleton getSingleton(){ //判读singleton是否为null,如果是null就创建,否者直接返回 if (singleton == null){ synchronized (Singleton.class){ if (singleton == null){ singleton = new Singleton(); } } } return singleton; } } 静态内部类实现

  • 静态内部类单例模式是一种优秀的单例模式,是比较常用的单例模式。在没有加任何锁时保证线程安全,并且没有任何性能影响和空间浪费。

  • 在加载Singleton时不会初始化singleton,只有第一次调用getSingleton()时。JVM加载SingletonHolder初始化singleton。

class Singleton{ //私有构造方法,这样外界就不能创建了 private Singleton(){ } //定义一个静态内部类 private static class SingletonHolder{ //只会初始化一次 private static final Singleton singleton= new Singleton(); } //给外界提供一个方法用于访问 public static synchronized Singleton getSingleton(){ return SingletonHolder.singleton; } } 破坏单例模式

  • 破坏单例模式的方式有两种一种是序列化反序列化,另一种是反射,这里我们指记录反射
  • 道高一尺,魔高一丈。有模式就会有破坏,有破坏还会有防破坏,但是还有反反破坏。这里面就多了。
通过反射破坏单例模式

package hello; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Hello { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //获取Singleton字节码对象 Class<Singleton> singletonClass = Singleton.class; //获取无参构造方法 Constructor<Singleton> declaredConstructor = singletonClass.getDeclaredConstructor(); //取消访问检查 declaredConstructor.setAccessible(true); //创建Singleton对象 Singleton singleton = (Singleton) declaredConstructor.newInstance(); Singleton singleton1 = (Singleton) declaredConstructor.newInstance(); //通过hashCode查看是否是同一个对象 System.out.println(singleton.hashCode()); System.out.println(singleton1.hashCode()); } } class Singleton{ //私有构造方法,这样外界就不能创建了 private Singleton(){ } //定义一个静态内部类 private static class SingletonHolder{ //只会初始化一次 private static final Singleton singleton= new Singleton(); } //给外界提供一个方法用于访问 public static synchronized Singleton getSingleton(){ return SingletonHolder.singleton; } } 单例模式优缺点

优点:

  • 单例模式在内存中只有一个实例,减少内存开支,特别是一个对象需要频繁地创建销毁时,而且创建或销毁时性能又无法优化,单例模式就非常明显了
  • 单例模式只生成一个实例,减少系统的性能开销
  • 单例模式可以避免对资源的多重占用
  • 单例模式可以在系统设置全局的访问点,优化和共享资源访问
    缺点:
  • 不适用于变化的对象
  • 由于单例模式没有抽象层,所以扩展困难
  • 单例类的职责过重,在一定程度上违背了“单一职责原则”
  • 单一职责原则:一个类,应该只有一个职责