国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

[Effective Java]第二章 創(chuàng)建和銷毀對象

2019-11-14 22:44:21
字體:
來源:轉載
供稿:網(wǎng)友
[Effective java]第二章 創(chuàng)建和銷毀對象聲明:原創(chuàng)作品,轉載時請注明文章來自SAP師太技術博客( 博/客/園www.cnblogs.com):m.survivalescaperooms.com/jiangzhengjun,并以超鏈接形式標明文章原始出處,否則將追究法律責任!原文鏈接:http://m.survivalescaperooms.com/jiangzhengjun/p/4254987.html 第一章 前言

略...

第二章 創(chuàng)建和銷毀對象 1、 考慮用靜態(tài)工廠方法代替構造器

創(chuàng)建對象方法:一是最常用的公有構造器,二是靜態(tài)工廠方法。下面是一個Boolean的簡單示例:

public static Boolean valueOf(boolean b) {

return (b ? Boolean.TRUE : Boolean.FALSE);

}

l靜態(tài)工廠方法與構造器不同的第一大優(yōu)勢在于,它們有名稱。

作用不同的公有構造器只能通過參數(shù)來區(qū)別(因為一個類只有一個帶有指定簽名的構造器,所以多個構造器只能使用不同的參數(shù)列表來區(qū)分),如果使用靜態(tài)的工廠方法,則方法名會很清楚地表達方法的作用。

l靜態(tài)工廠方法與構造器不同的第二大優(yōu)勢在于,不必在每次調用它們的時候都創(chuàng)建一個新對象。

不可變類完全可以使用預先構建好的實例,而不必每次使用時都創(chuàng)建一個對象。另外,將構建好的實例緩存起來重復使用,從而避免創(chuàng)建不必要的重復對象。Boolean.valueOf(boolean)方法就使用了這項技術——它從來不創(chuàng)建對象。

l靜態(tài)工廠方法與構造器不同的第三大優(yōu)勢在于,它們可以返回原返回類型的任何子類型的對象。

這樣我們在選擇返回對象的類時就有了更大的靈活性。這種靈活性的一種應用是,API可以返回對象,同時又不會使對象的類變成公有的,比如我們完全可以先定義一個產(chǎn)品接口類,然后采用私有的內部類去實現(xiàn)這個接口,靜態(tài)工廠方法返回這個類的實例,這樣就隱藏了具體的實現(xiàn)。另外,使用靜態(tài)工廠方時,要求客戶端通過接口來引用被返回的對象,而不是通過它的實現(xiàn)類來引用被返回的對象,這是一種良好的編程習慣。

公有靜態(tài)工廠方法所返回的對象的類不僅可以是PRivate,而且通過靜態(tài)工廠方法的參數(shù),還可以隨著每次的返回不同的類的實例,只要是已聲明返回類型的子類型。這樣的好處是,可以在以后的版本中刪除這個類重新實現(xiàn)也不會影響到已使用的客戶。

靜態(tài)工廠方法返回的對象所屬的類,在編寫包含該靜態(tài)工廠方法的類時可能不必存在。這種靈活的靜態(tài)工廠方法構成了服務提供者框架的基礎,例如JDBC API。服務提供者框架是指這樣一個系統(tǒng):多個服務提供者實現(xiàn)一個服務,系統(tǒng)為服務提供者的客戶端提供多個實現(xiàn),并把他們從多個實現(xiàn)中解耦出來。

服務提供者框架有三個重要組件:服務接口(Service Interface),這是提供者實現(xiàn)的;提供者注冊API(Provider Registration API),這是系統(tǒng)用來注冊實現(xiàn),讓客戶端訪問它們的;服務訪問API(Service access API),是客戶端用來獲取服務的實例的方法接口。服務訪問API一般允許但是不要求客戶端指定某種選擇提供者的條件。如果沒有這樣的規(guī)定,API就會返默認實現(xiàn)的一個實例。服務訪問API是“靈活的靜態(tài)工廠”,它構成了服務提供者框架的基礎。

服務提供者框架的第四個組件是可選的:服務提供者接口(Service Provider Interface)(即工廠方法模式中的工廠接口),這些提供者負責創(chuàng)建其服務實現(xiàn)的實例。如果沒有服務提供者接口,實現(xiàn)就按照類名稱注冊,并通過反射方式進行實例化。對于JDBC來說,Connection就是它的服務接口,DriverManager.registerDriver是提供者注冊API,DriverManager.getConnection是服務訪問API,Driver就是服務提供者接口。

下面看看這四個組件的應用:

//服務接口,就是我們的業(yè)務接口。(相當于Connection接口,由Sun提供)

publicinterfaceService {

// ...

}

//服務提供都接口,即業(yè)務工廠接口。(相當于Driver接口,由第三方廠家實現(xiàn))

publicinterfaceProvider{

Service newService();

}

//服務提供者注冊與服務提供者接口(好比DriverManager)

publicclassServices{

privateServices() {}

//服務名與服務映射,即注冊容器

privatestaticfinalMapproviders=newConcurrentHashMap();

publicstaticfinalStringDEFAULT_PROVIDER_NAME= "def";

//服務提供者注冊API,即注冊工廠實現(xiàn),相當于DriverManager.registerDriver

publicstaticvoidregisterDefaultProvider(Provider p) {

registerProvider(DEFAULT_PROVIDER_NAME, p);

}

publicstaticvoidregisterProvider(String name, Provider p) {

providers.put(name, p);

}

//服務訪問API,向外界提供業(yè)務實現(xiàn),相當于DriverManager.getConnection

publicstaticService newInstance() {

returnnewInstance(DEFAULT_PROVIDER_NAME);

}

publicstaticService newInstance(String name) {

Provider p = (Provider)providers.get(name);

if(p ==null) {

thrownewIllegalArgumentException(

"NO provider registered with name:" + name);

}

returnp.newService();

}

}

靜態(tài)工廠方法的第四大優(yōu)勢在于,在創(chuàng)建參數(shù)化類型實例的時候,它們使代碼變得更加簡潔。比如要創(chuàng)建一個參數(shù)化的HashMap,我們需要如下做:

Map<String,List<String>>m=newHashMap<String, List<String>>();

這么長的類型參數(shù)實在是不太好,而且隨著類型參數(shù)變得越來越長,也越來越復雜。但如果有了靜態(tài)工廠方法,編譯器就可以替你推導出類型,new時不需要提供參數(shù)類型。例如,假設HashMap提供了這個靜態(tài)工廠:

publicstatic<k,v> HashMap<k,v>newInstance(){

returnnewHashMap<k,v>();

}

那么你就可以使用以下簡潔的代碼來代替上面這段繁瑣的聲明:

Map<String,List<String>>m= HashMap.newInstance();

但可惜的是,到現(xiàn)在發(fā)行的版本1.6止還未加入,不過我們可以把這些方法放在自己的工具類中。

靜態(tài)工廠方法的一些慣用名稱:

valueOf——不太嚴格地講,該方返回的實例與它的參數(shù)具有相同的值。這樣的靜態(tài)工廠方法實際上是類型轉換方法。

of——valueOf的一種更為簡潔的替換,在EnumSet中使用并流行起來。

getInstance——返回的實例是通過方法的參數(shù)來描述的,但是不能夠說與參數(shù)具有同樣的值。對于Singleton來說,該方法沒有參數(shù),并返回唯一值。

newInstance——像getInstance一樣,但newInstance能夠確保返回每個實例都與把有其他實例不同。

getType——像getInstance一樣,但是在工廠方法處于不同的類中的時候使用。Type表示工廠方法所返回的對象類型。

newType——像newInstance一樣,但是在工廠方法處于不同的類中的時候使用。Type表示工廠方法所返回的對象類型。

2、 遇到多個構造器參數(shù)時要考慮構造器

如果實例化時需要多個參數(shù)時,且這些參數(shù)中只有少數(shù)幾個是必須的,而很多是可選的,這時我們一般考慮使用構造器的方式,而不是使用靜態(tài)工廠方法。

對于此情況,我們可以使用重疊構造器模式——你提供一個只有必要參數(shù)的構造器,第二構造器有一個可選參數(shù),第三個有兩個可選參數(shù),依此類推,最后一個構造器包含所有可選參數(shù)。

publicclassNutritionFacts {

privatefinalintservingSize; //必選參數(shù)

privatefinalintservings; //必選參數(shù)

privatefinalintcalories; //可選參數(shù)

privatefinalintfat; //可選參數(shù)

privatefinalintsodium; //可選參數(shù)

privatefinalintcarbohydrate; //可選參數(shù)

//第一個構造器帶上所有必選參數(shù)

publicNutritionFacts(intservingSize,intservings) {

//調用另一個構造器

this(servingSize, servings, 0);//第三個參數(shù)為默認值

}

//第二個構造器在第一個構造器的基礎上加上一個可先參數(shù)

publicNutritionFacts(intservingSize,intservings,

intcalories) {

//第四個參數(shù)為默認值

this(servingSize, servings, calories, 0);

}

Word-spacing: 0px; text-transform: none; margin: 0cm 0cm 0pt; letter-spacing: normal; line-height: normal; text-indent: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-wid

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 阜宁县| 栾城县| 绩溪县| 遂川县| 兴安盟| 仁怀市| 河东区| 沙坪坝区| 且末县| 桑植县| 海淀区| 邵阳市| 花莲县| 娱乐| 新建县| 河源市| 景宁| 普兰店市| 林甸县| 拜城县| 庆城县| 汕尾市| 吉木萨尔县| 斗六市| 孝感市| 彰化市| 晋中市| 河源市| 河间市| 凤阳县| 泰和县| 民乐县| 阿拉善盟| 修武县| 普宁市| 荥阳市| 莫力| 黄山市| 青海省| 崇义县| 石家庄市|