eff实现单例的3种方式

  1 package eff;
  2  
  3  import java.lang.reflect.Constructor;
  4  import java.lang.reflect.InvocationTargetException;
  5  
  6  /**
  7   * 
  8   * @author lw
  9   * 
 10   */
 11  public class SingleSimpleTest {
 12      public static void main(String[] args) {
 13          try {
 14              testSingle();
 15          } catch (Exception e) {
 16              // TODO Auto-generated catch block
 17              e.printStackTrace();
 18          }
 19      }
 20  
 21      private static void testSingle() throws ClassNotFoundException,
 22              SecurityException, NoSuchMethodException, IllegalArgumentException,
 23              InstantiationException, IllegalAccessException,
 24              InvocationTargetException {
 25          Single1 s1 = Single1.newInstance();
 26          Constructor c = Class.forName("eff.Single1").getDeclaredConstructor(
 27                  null);
 28          c.setAccessible(true);
 29          Single1 _s1 = (Single1) c.newInstance(null);
 30          System.out.println("懒汉Single pattern 测试结果 S1=_S1?: "
 31                  + (s1 == _s1 ? "SUCCESS" : "FAIL"));
 32  
 33          Single2 s2 = Single2.newInstance();
 34          Constructor c2 = Class.forName("eff.Single2").getDeclaredConstructor(
 35                  null);
 36          c2.setAccessible(true);
 37          Single2 _s2 = (Single2) c2.newInstance(null);
 38          System.out.println("饿汉Single pattern 测试结果 S2=_S2?: "
 39                  + (s2 == _s2 ? "SUCCESS" : "FAIL"));
 40  
 41          Single3 s3 = Single3.newInstance();
 42          Constructor c3 = Class.forName("eff.Single3").getDeclaredConstructors()[0];
 43          c3.setAccessible(true);
 44          System.out.println(c3.newInstance(null) == c3);
 45          c3.setAccessible(true);
 46          Single3 _s3 = (Single3) c3.newInstance(null);
 47          System.out.println("枚举Single pattern 测试结果 S3=_S3?: "
 48                  + (c3.newInstance(null) == c3 ? "SUCCESS" : "FAIL"));
 49      }
 50  }
 51  
 52  /**
 53   * 懒汉Single pattern
 54   * 
 55   * @author lw
 56   * 
 57   */
 58  class Single1 {
 59      private static final Single1 INSTANCE = new Single1();
 60  
 61      private Single1() {
 62      };
 63  
 64      public static Single1 newInstance() {
 65          return INSTANCE;
 66      }
 67  }
 68  
 69  /**
 70   * 饿汉 Single pattern
 71   * 
 72   * @author lw
 73   * 
 74   */
 75  class Single2 {
 76      private static Single2 INSTANCE;
 77  
 78      private static boolean isInstance;
 79  
 80      private Single2() {
 81          /* 此处的构造器被强化 */
 82          if (isInstance) {
 83              throw new RuntimeException("对象已经存在,无法创建第二个对象");
 84          }
 85          isInstance = true;
 86      };
 87  
 88      public static Single2 newInstance() {
 89          if (null == INSTANCE) {
 90              INSTANCE = new Single2();
 91          }
 92          return INSTANCE;
 93      }
 94  }
 95  
 96  /**
 97   * 枚举 Single pattern 这种方法在功能与公有域方法相近,但是它更简洁,无偿的提供了序列化机制
 98   * 绝对防止多次实例化,即使在面对复杂的序列化或者反射攻击的时候。 虽然这种方法没有广泛采用,但是单元素的枚举类型以及成为事件Singleton的最佳方法。
 99   * 
100   * @author lw
101   * 
102   */
103  enum Single3 {
104  
105      INSTANCE;
106  
107      public static Single3 newInstance() {
108          return INSTANCE;
109      }
110  }
原文地址:https://www.cnblogs.com/lw900320/p/2587956.html