一、概念
專(zhuān)注于為中小企業(yè)提供網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)彝良免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
單例模式是一種常用的軟件設(shè)計(jì)模式。在它的核心結(jié)構(gòu)中只包含一個(gè)被稱(chēng)為單例類(lèi)的特殊類(lèi)。通過(guò)單例模式可以保證系統(tǒng)中一個(gè)類(lèi)只有一個(gè)實(shí)例而且該實(shí)例易于外界訪問(wèn),從而方便對(duì)實(shí)例個(gè)數(shù)的控制并節(jié)約系統(tǒng)資源。如果希望在系統(tǒng)中某個(gè)類(lèi)的對(duì)象只能存在一個(gè),單例模式是最好的解決方案。就筆者認(rèn)為,單例就是不讓外界創(chuàng)建對(duì)象。
1.1概念剖析
對(duì)于單例的話,從上面的概念剖析,應(yīng)該滿足下面的幾個(gè)條件:
第一:?jiǎn)卫?lèi)中只能有一個(gè)單例對(duì)象;
第二:?jiǎn)卫?lèi)必須自己創(chuàng)建自己的唯一實(shí)例對(duì)象;
第三:這個(gè)實(shí)例對(duì)象能夠給外界訪問(wèn)到,并且外界不能夠自己創(chuàng)建對(duì)象。
二、常見(jiàn)幾種單例模式的方式
在java中,對(duì)于單例模式一般來(lái)說(shuō),分為懶漢式,餓漢式,以及登記式,但是登記式一般較少看到,所以也容易忽略。筆者若非今天突然想總結(jié)一下,在網(wǎng)上查找資料,也不會(huì)注意到這個(gè)。下面按照這種方式來(lái)貼出代碼,并進(jìn)行解釋。
2.1餓漢式單例類(lèi)
package com.ygh.singleton; /** * 餓漢式單例類(lèi) * @author 夜孤寒 * @version 1.1.1 */ public class HungerSingleton { //將構(gòu)造方法私有,外界類(lèi)不能使用構(gòu)造方法new對(duì)象 private HungerSingleton(){} //創(chuàng)建一個(gè)對(duì)象 private static final HungerSingleton lazySinleton=new HungerSingleton(); //設(shè)置實(shí)例獲取方法,返回實(shí)例給調(diào)用者 public static HungerSingleton getInstance(){ return lazySinleton; } }
寫(xiě)一個(gè)測(cè)試類(lèi),測(cè)試是不是實(shí)現(xiàn)單例:
package com.ygh.singleton; /** * 測(cè)試單例類(lèi) * * @author 夜孤寒 * @version 1.1.1 */ public class Test { public static void main(String[] args) { /* * 構(gòu)造方法私有化,不能夠使用下面方式new對(duì)象 */ //HungerSingleton hungerSingleton=new HungerSingleton(); //使用實(shí)例獲取方法來(lái)獲取對(duì)象 HungerSingleton h2=HungerSingleton.getInstance(); HungerSingleton h3=HungerSingleton.getInstance(); System.out.println(h2==h3);//true } }
從上面可以看出:這個(gè)測(cè)試類(lèi)的兩個(gè)引用是相等的,也就是說(shuō)兩個(gè)引用指向的是同一個(gè)對(duì)象,而這也正好符合單例模式標(biāo)準(zhǔn)。到這里,餓漢式介紹結(jié)束。
2.2餓漢式單例類(lèi)
package com.ygh.singleton; /** * 懶漢式單例類(lèi) * @author 夜孤寒 * @version 1.1.1 */ public class LazySingleton { //將構(gòu)造方法私有,外界類(lèi)不能使用構(gòu)造方法new對(duì)象 private LazySingleton(){} //創(chuàng)建一個(gè)對(duì)象,不為final private static LazySingleton lazySingleton=null; //設(shè)置實(shí)例獲取方法,返回實(shí)例給調(diào)用者 public static LazySingleton getInstance(){ //當(dāng)單例對(duì)象不存在,創(chuàng)建 if(lazySingleton==null){ lazySingleton=new LazySingleton(); } //返回 return lazySingleton; } }
測(cè)試類(lèi):
package com.ygh.singleton; /** * 測(cè)試單例類(lèi) * * @author 夜孤寒 * @version 1.1.1 */ public class Test { public static void main(String[] args) { /* * 構(gòu)造方法私有化,不能夠使用下面方式new對(duì)象 */ //LazySingleton lazySingleton=new LazySingleton(); //使用實(shí)例獲取方法來(lái)獲取對(duì)象 LazySingleton l1=LazySingleton.getInstance(); LazySingleton l2=LazySingleton.getInstance(); System.out.println(l1==l2);//true } }
從上面可以看出:這個(gè)測(cè)試類(lèi)的兩個(gè)引用是相等的,也就是說(shuō)兩個(gè)引用指向的是同一個(gè)對(duì)象,而這也正好符合單例模式標(biāo)準(zhǔn)。到這里,懶漢式介紹結(jié)束。
2.3懶漢式和餓漢式的區(qū)別
懶漢式是當(dāng)沒(méi)有對(duì)象的時(shí)候,就會(huì)創(chuàng)建一個(gè)單例對(duì)象,當(dāng)有對(duì)象的時(shí)候,就不會(huì)再創(chuàng)建對(duì)象,這個(gè)說(shuō)起來(lái)可能不是那么容易理解,但是讀者如果有興趣了解更深,可以在eclipse中使用斷點(diǎn)來(lái)測(cè)試,將LazySingleton類(lèi)的if花括號(hào)內(nèi)的內(nèi)容加上斷點(diǎn),然后在Test類(lèi)中,使用debug運(yùn)行,這樣子就能夠很容易體現(xiàn)出來(lái),第一次創(chuàng)建了一個(gè)對(duì)象,但是第二次沒(méi)有創(chuàng)建對(duì)象。
餓漢式則是實(shí)現(xiàn)就用final這個(gè)關(guān)鍵字將對(duì)象創(chuàng)建好了,當(dāng)調(diào)用者需要實(shí)例對(duì)象的時(shí)候,就可以通過(guò)getInstance這個(gè)方法獲取創(chuàng)建好的實(shí)例。
2.4登記式單例類(lèi)
對(duì)于登記式單例類(lèi),筆者也不是很熟悉,貼了一段網(wǎng)絡(luò)上的代碼以供自己學(xué)習(xí)參考,請(qǐng)讀者自行學(xué)習(xí)。
import java.util.HashMap; import java.util.Map; /** * 登記式單例類(lèi) * @author Administrator * */ public class RegisterSingleton { private static Mapmap = new HashMap (); static { RegisterSingleton single = new RegisterSingleton(); map.put(single.getClass().getName(), single); } /* * 保護(hù)的默認(rèn)構(gòu)造方法 */ protected RegisterSingleton() { } /* * 靜態(tài)工廠方法,返還此類(lèi)惟一的實(shí)例 */ 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); } /* * 一個(gè)示意性的商業(yè)方法 */ public String about() { return "Hello, I am RegSingleton."; } public static void main(String[] args) { RegisterSingleton single3 = RegisterSingleton.getInstance(null); System.out.println(single3.about()); } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。