黑馬程序員-通過枚舉實現單例模式

------- android培訓java培訓、期待與您交流! ----------


單例模式:就是讓該類在內存中只存在一個對象

單例模式有兩種方法一個是餓漢式,一個是懶漢式

/**
*單例設計模式:餓漢式
*/
class Single
{
	private static Single s = new Single();
	private Single(){}
	public static Single getInstance()
	{
		return s;
	}
}

/**
*單例設計模式:懶漢式
*/
class Single
{
	private static Single s = null;
	private Single(){}
	public static getInstance()
	{
		if(s==null)
		{
			synchronized(Single.class)	//給這個類加鎖
			{
				if(s==null)
					s = new Single();
				return s;
			}
		}
	}
}

由於可以通過反射來建立好多類的實例,所以出現了安全隱患。java 1.5 以後可以通過枚舉來實現單例模式,更加可靠


import java.lang.reflect.Constructor;
/**
 * 測試Singleton的可靠性。
 * 
 */
public class TestSingleton {
  public static void main(String[] args) {
    testSingleton1();
    testSingleton2();
    testSingleton3();
  }
  public static void testSingleton1() {
    try {
      // 測試Singletom1
      // 拿到第一個實例
      TestSingleton1 s1 = TestSingleton1.getInstance();
      // 測試拿到第二個實例
      Class c1 = Class.forName("TestSingleton1");
      Constructor[] cons = c1.getDeclaredConstructors();
      Constructor cc1 = cons[0];
      cc1.setAccessible(true);
      TestSingleton1 s2 = (TestSingleton1) cc1.newInstance(null);
      System.out.println(s1 + "/" + s2);
      System.out.println(s1 == s2);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  public static void testSingleton2() {
    try {
      // 測試Singletom1
      // 拿到第一個實例
      TestSingleton2 s1 = TestSingleton2.getInstance();
      // 測試拿到第二個實例
      Class c1 = Class.forName("TestSingleton2");
      Constructor[] cons = c1.getDeclaredConstructors();
      Constructor cc1 = cons[0];
      cc1.setAccessible(true);
      TestSingleton2 s2 = (TestSingleton2) cc1.newInstance(null);
      System.out.println(s1 + "/" + s2);
      System.out.println(s1 == s2);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  public static void testSingleton3() {
    try {
      // 測試Singletom1
      // 拿到第一個實例
      TestSingleton3 s1 = TestSingleton3.getInstance();
      // 測試拿到第二個實例
      Class c1 = Class.forName("TestSingleton3");
      Constructor[] cons = c1.getDeclaredConstructors();
      Constructor cc1 = cons[0];
      cc1.setAccessible(true);
      TestSingleton3 s2 = (TestSingleton3) cc1.newInstance(null);
      System.out.println(s1 + "/" + s2);
      System.out.println(s1 == s2);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}
/**
 * 一個普通的Singletone實現。
 * 
 */
class TestSingleton1 {
  private static final TestSingleton1 INSTANCE = new TestSingleton1();
  public static TestSingleton1 getInstance() {
    return INSTANCE;
  }
  private TestSingleton1() {
  }
}
/**
 * 一個用異常強化了的Singletone實現。
 * 
 */
class TestSingleton2 {
  private static final TestSingleton2 INSTANCE = new TestSingleton2();
  public static TestSingleton2 getInstance() {
    return INSTANCE;
  }
  private static boolean initSign;
  private TestSingleton2() {
    if (initSign) {
      throw new RuntimeException("實例只能建造一次");
    }
    initSign = true;
  }
}
/**
 * 枚舉實現的Singleton
 * 
 */
enum TestSingleton3 {
  INSTANCE;
  public static TestSingleton3 getInstance() {
    return INSTANCE;
  }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章