JDK源碼解讀單例模式與工廠模式

點(diǎn)擊上方「藍(lán)字」關(guān)注我們

0x01:?jiǎn)卫J?/strong>
java.lang.Runtime
public?class?Runtime?{
????//單例成員變量
????private?static?Runtime?currentRuntime?=?new?Runtime();
????//獲取單例
????public?static?Runtime?getRuntime()?{
????????return?currentRuntime;
????}
????//私有構(gòu)造方法
????private?Runtime()?{}
???//省略?.....
}
? ? ? ?從源碼看標(biāo)準(zhǔn)的餓漢模式,Runtime類封裝了Java運(yùn)行時(shí)的環(huán)境。每一個(gè)java程序?qū)嶋H上都是啟動(dòng)了一個(gè)JVM進(jìn)程,那么每個(gè)JVM進(jìn)程都是對(duì)應(yīng)這一個(gè)Runtime實(shí)例,此實(shí)例是由JVM為其實(shí)例化的。每個(gè) Java 應(yīng)用程序都有一個(gè) Runtime 類實(shí)例,使應(yīng)用程序能夠與其運(yùn)行的環(huán)境相連接。
? ? ? ? 在Java的GUI編程接口上也有幾個(gè)單例模式的實(shí)現(xiàn),但是Java的GUI編程在國(guó)內(nèi)幾乎被淘汰了,這里就不介紹了。
0x02:工廠模式
java.util.Calendar
public?abstract?class?Calendar?implements?Serializable,?Cloneable,?Comparable<Calendar>?{
?????public?static?Calendar?getInstance(TimeZone?zone,
???????????????????????????????????????Locale?aLocale){
????????return?createCalendar(zone,?aLocale);
????}
????private?static?Calendar?createCalendar(TimeZone?zone,
???????????????????????????????????????????Locale?aLocale)
????{
????????CalendarProvider?provider?=
????????????LocaleProviderAdapter.getAdapter(CalendarProvider.class,?aLocale)
?????????????????????????????????.getCalendarProvider();
????????if?(provider?!=?null)?{
????????????try?{
????????????????return?provider.getInstance(zone,?aLocale);
????????????}?catch?(IllegalArgumentException?iae)?{
????????????????//?fall?back?to?the?default?instantiation
????????????}
????????}
????????Calendar?cal?=?null;
????????if?(aLocale.hasExtensions())?{
????????????String?caltype?=?aLocale.getUnicodeLocaleType("ca");
????????????if?(caltype?!=?null)?{
????????????????switch?(caltype)?{
????????????????case?"buddhist":
????????????????cal?=?new?BuddhistCalendar(zone,?aLocale);
????????????????????break;
????????????????case?"japanese":
????????????????????cal?=?new?JapaneseImperialCalendar(zone,?aLocale);
????????????????????break;
????????????????case?"gregory":
????????????????????cal?=?new?GregorianCalendar(zone,?aLocale);
????????????????????break;
????????????????}
????????????}
????????}
????????if?(cal?==?null)?{strings?are?interned.
????????????if?(aLocale.getLanguage()?==?"th"?&&?aLocale.getCountry()?==?"TH")?{
????????????????cal?=?new?BuddhistCalendar(zone,?aLocale);
????????????}?else?if?(aLocale.getVariant()?==?"JP"?&&?aLocale.getLanguage()?==?"ja"
???????????????????????&&?aLocale.getCountry()?==?"JP")?{
????????????????cal?=?new?JapaneseImperialCalendar(zone,?aLocale);
????????????}?else?{
????????????????cal?=?new?GregorianCalendar(zone,?aLocale);
????????????}
????????}
????????return?cal;
????}
????//省略......
}
分析源碼可以知道Calendar使用了簡(jiǎn)單工廠模式,通過(guò)getInstance()方法進(jìn)去,而getInstance()方法調(diào)用了createCalendar()方法。

javax.xml.parsers.DocumentBuilderFactory
????public?static?DocumentBuilderFactory?newInstance()?{
????????return?FactoryFinder.find(
????????????????DocumentBuilderFactory.class,?
????????????????"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
????}
????public?static?DocumentBuilderFactory?newInstance(String?factoryClassName,?ClassLoader?classLoader){
????????????return?FactoryFinder.newInstance(DocumentBuilderFactory.class,
????????????????????????factoryClassName,?classLoader,?false);
????}
????public?abstract?DocumentBuilder?newDocumentBuilder()
????????throws?ParserConfigurationException;
? ? ? ?javax.xml.parses包的DocumentBuilderFactory用于創(chuàng)建DOM模式的解析器對(duì)象,DocumentBuilderFactory是一個(gè)抽象工廠類,它不能直接實(shí)例化,但該類提供了一個(gè)newInstance方法,這個(gè)方法會(huì)根據(jù)本地平臺(tái)默認(rèn)安裝的解析器,自動(dòng)創(chuàng)建一個(gè)工廠的對(duì)象并返回。
? ? 從DocumentBuilderFactory源碼上看提供了一個(gè)默認(rèn)的實(shí)現(xiàn)DocumentBuilderFactoryImpl.java,看到該類的newDocumentBuilder,可以看出只要調(diào)用newInstance()方法就會(huì)返回一個(gè)新的DocumentBuilder?對(duì)象
???public?DocumentBuilder?newDocumentBuilder()
????????throws?ParserConfigurationException
????{
????????if?(grammar?!=?null?&&?attributes?!=?null)?{
????????????if?(attributes.containsKey(JAXPConstants.JAXP_SCHEMA_LANGUAGE))?{
????????????????throw?new?ParserConfigurationException(
????????????????????????SAXMessageFormatter.formatMessage(null,
????????????????????????"schema-already-specified",?new?Object[]?{JAXPConstants.JAXP_SCHEMA_LANGUAGE}));
????????????}
????????????else?if?(attributes.containsKey(JAXPConstants.JAXP_SCHEMA_SOURCE))?{
????????????????throw?new?ParserConfigurationException(
????????????????????????SAXMessageFormatter.formatMessage(null,
????????????????????????"schema-already-specified",?new?Object[]?{JAXPConstants.JAXP_SCHEMA_SOURCE}));
????????????}
????????}
????????try?{
????????????return?new?DocumentBuilderImpl(this,?attributes,?features,?fSecureProcess);
????????}?catch?(SAXException?se)?{
????????????throw?new?ParserConfigurationException(se.getMessage());
????????}
????}
掃碼二維碼
獲取更多精彩
Java樂(lè)園

