首頁  >  文章  >  Java  >  Java中關於單例模式簡單介紹

Java中關於單例模式簡單介紹

黄舟
黄舟原創
2017-10-12 10:17:131322瀏覽

這篇文章主要為大家詳細介紹了Java單例模式簡單的相關資料,具有一定的參考價值,有興趣的小夥伴們可以參考一下

一、概念

單例模式是一種常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例類別的特殊類別。透過單例模式可以確保系統中一個類別只有一個實例而且該實例易於外界訪問,從而方便對實例個數的控制並節約系統資源。如果希望在系統中某個類別的物件只能存在一個,單例模式是最好的解決方案。就筆者認為,單例就是不讓外界創建物件。

1.1概念剖析

對於單例的話,從上面的概念剖析,應該滿足下面的幾個條件:

第一:單例類別中只能有一個單例物件;

第二:單例類別必須自己創建自己的唯一實例物件;

#第三:這個實例物件能夠給外界存取到,並且外界不能夠自己創建對象。

二、常見幾種單例模式的方式

在java中,對於單例模式一般來說,分為懶漢式,餓漢式,以及登記式,但是登記式一般較少看到,所以也容易忽略。筆者若非今天突然想總結一下,在網路上找資料,也不會注意到這個。下面按照這種方式來貼出程式碼,並進行解釋。

2.1餓漢式單例類


package com.ygh.singleton;
/**
 * 饿汉式单例类
 * @author 夜孤寒
 * @version 1.1.1
 */
public class HungerSingleton {
  //将构造方法私有,外界类不能使用构造方法new对象
  private HungerSingleton(){}
  //创建一个对象
  private static final HungerSingleton lazySinleton=new HungerSingleton();
  //设置实例获取方法,返回实例给调用者
  public static HungerSingleton getInstance(){
    return lazySinleton;
  }
}

寫一個測試類,測試是不是實作單例:


package com.ygh.singleton;
/**
 * 测试单例类
 * 
 * @author 夜孤寒
 * @version 1.1.1
 */
public class Test {
  public static void main(String[] args) {
    /*
     * 构造方法私有化,不能够使用下面方式new对象
     */
    //HungerSingleton hungerSingleton=new HungerSingleton();
    //使用实例获取方法来获取对象
    HungerSingleton h1=HungerSingleton.getInstance();
    HungerSingleton h2=HungerSingleton.getInstance();
    System.out.println(h1==h2);//true
  }
}

從上面可以看出:這個測試類的兩個引用是相等的,也就是說兩個引用指向的是同一個對象,而這也剛好符合單例模式標準。到這裡,餓漢式介紹結束。

2.2餓漢式單例類別


package com.ygh.singleton;
/**
 * 懒汉式单例类
 * @author 夜孤寒
 * @version 1.1.1
 */
public class LazySingleton {
  //将构造方法私有,外界类不能使用构造方法new对象
  private LazySingleton(){}
  //创建一个对象,不为final
  private static LazySingleton lazySingleton=null;
  //设置实例获取方法,返回实例给调用者
  public static LazySingleton getInstance(){
    //当单例对象不存在,创建
    if(lazySingleton==null){
      lazySingleton=new LazySingleton();
    }
    //返回
    return lazySingleton;
  }
}

測試類別:


package com.ygh.singleton;
/**
 * 测试单例类
 * 
 * @author 夜孤寒
 * @version 1.1.1
 */
public class Test {
  public static void main(String[] args) {
    /*
     * 构造方法私有化,不能够使用下面方式new对象
     */
    //LazySingleton lazySingleton=new LazySingleton();
    //使用实例获取方法来获取对象
    LazySingleton l1=LazySingleton.getInstance();
    LazySingleton l2=LazySingleton.getInstance();
    System.out.println(l1==l2);//true
  }
}

從上面可以看出:這個測試類別的兩個引用是相等的,也就是說兩個引用指向的是同一個對象,而這也剛好符合單例模式標準。到這裡,懶漢式介紹結束。

2.3懶漢式和餓漢式的區別

懶漢式是當沒有對象的時候,就會創建一個單例對象,當有對象的時候,就不會再創建對象,這個說起來可能不是那麼容易理解,但是讀者如果有興趣了解更深,可以在eclipse中使用斷點來測試,將LazySingleton類的if花括號內的內容加上斷點,然後在Test類中,使用debug運行,這樣子就能夠很容易體現出來,第一次創建了一個對象,但是第二次沒有創建對象。

餓漢式則是實作就用final這個關鍵字將物件創建好了,當呼叫者需要實例物件的時候,就可以透過getInstance這個方法取得創建好的實例。

2.4登記式單例類

對於登記式單例類,筆者也不是很熟悉,貼了一段網絡上的代碼以供自己學習參考,請讀者自行學習。


import java.util.HashMap;
import java.util.Map;

/**
 * 登记式单例类
 * @author Administrator
 *
 */
public class RegisterSingleton {
 private static Map<String, RegisterSingleton> map = new HashMap<String, RegisterSingleton>();
 static {
  RegisterSingleton single = new RegisterSingleton();
  map.put(single.getClass().getName(), single);
 }

 /*
  * 保护的默认构造方法
  */
 protected RegisterSingleton() {
 }

 /*
  * 静态工厂方法,返还此类惟一的实例
  */
 public static RegisterSingleton getInstance(String name) {
  if (name == null) {
   name = RegisterSingleton.class.getName();
   System.out.println("name == null" + "--->name=" + name);
  }
  if (map.get(name) == null) {
   try {
    map.put(name, (RegisterSingleton) Class.forName(name).newInstance());
   } catch (InstantiationException e) {
    e.printStackTrace();
   } catch (IllegalAccessException e) {
    e.printStackTrace();
   } catch (ClassNotFoundException e) {
    e.printStackTrace();
   }
  }
  return map.get(name);
 }

 /*
  * 一个示意性的商业方法
  */
 public String about() {
  return "Hello, I am RegSingleton.";
 }

 public static void main(String[] args) {
  RegisterSingleton single3 = RegisterSingleton.getInstance(null);
  System.out.println(single3.about());
 }
}

以上是Java中關於單例模式簡單介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn