




下載本文檔
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第2章 創(chuàng)建和銷毀對象本章的主題是創(chuàng)建和銷毀對象:何時以及如何創(chuàng)建對象,何時以及如何避免創(chuàng)建對象,如何確保它們能夠被適時地銷毀,以及如何管理銷毀之前必須進行的所有清除動作。第1條:考慮用靜態(tài)工廠方法代替構造器對于類而言,為了讓客戶端獲取它自身的一個實例,最常用的方法就是提供一個公有的構造器。還有一種方法,也應該成為每個程序員的工具箱中的一部分。類可以提供一個公有的靜態(tài)工廠方法(static factory method),它只是一個返回類的實例的靜態(tài)方法。下面是一個來自Boolean(基本類型boolean的包裝類)的簡單示例。這個方法將boolean基本類型值轉換成了一個Boolean對象引
2、用:public static Boolean valueOf(boolean b) return b ? Boolean.TRUE : Boolean.FALSE;注意,靜態(tài)工廠方法與設計模式(Design Patterns)Gamma95, p.107中的工廠方法(Factory Method)模式不同。本條目中所指的靜態(tài)工廠方法并不直接對應于設計模式中的工廠方法。類可以通過靜態(tài)工廠方法來提供它的客戶端,而不是通過構造器。提供靜態(tài)工廠方法而不是公有的構造器具有兩大優(yōu)勢。靜態(tài)工廠方法與構造器不同的第一大優(yōu)勢在于,它們有名稱。如果構造器的參數本身沒有確切地描述正被返回的對象,那么具有適當名稱的
3、靜態(tài)工廠會更容易使用,產生的客戶端代碼也更易于閱讀。例如,構造器BigInteger(int, int, Random)返回的BigInteger可能為素數(prime),如果用名為BigIbablePrime的靜態(tài)工廠方法來表示,顯然要好一些。(1.4的發(fā)行版本中最終增加了這個方法。)一個類只能有一個帶有指定簽名的構造器。編程人員通常知道如何避開這一限制:通過提供兩個構造器,它們的參數列表只在參數類型的順序上有所不同。實際上這并不是個好主意。這種API的用戶永遠也不會記得哪個構造器是哪個,最終會導致調用錯誤的構造器。人們讀到使用了這些構造器的代碼時,如果沒有參考類的文檔,
4、往往不知道這段代碼是做什么用的。由于靜態(tài)工廠方法有名稱,所以它們沒有像前一段落中所談到那種限制。如果一個類可能需要多個帶有相同簽名的構造器時,就用靜態(tài)工廠方法代替構造器,并且慎重地選擇名稱以便突出它們之間的區(qū)別。靜態(tài)工廠方法與構造器不同的第二大優(yōu)勢在于,不必在每次調用它們的時候都創(chuàng)建一個新對象。這使得不可變的類(見第15條)可以使用預先構建好的實例,或者將構建好的實例緩存起來,進行重復分發(fā),以避免重復創(chuàng)建不必要的對象。Boolean.valueOf(boolean)方法示范了這種方法:它從來不創(chuàng)建對象。這種方法類似于Flyweight模式Gamma95,p.195。如果程序經常請求相同的對象,
5、尤其當創(chuàng)建對象的成本很高時,這種方法可以極大地提升性能。靜態(tài)工廠方法能夠為重復的調用返回相同對象,這樣有助于類總能嚴格控制在某個時刻哪些實例應該存在。這種類被稱作實例受控的類(instance-controlled)。編寫實例受控的類有幾個原因。實例受控使得類可以確保它是一個Singleton(見第3條)或者是不可實例化的(見第4條)。它還使得不可變的類(見第15條)可以確保不會存在兩個相等的實例,即當且僅當a=b的時候才有a.equals(b)。如果類保證了這一點,它的客戶端就可以使用=操作符來代替equals(Object)方法,這樣可以提升性能。枚舉(enum)類型(第30條)保證了這一
6、點。靜態(tài)工廠方法與構造器不同的第三大優(yōu)勢在于,它們可以返回原返回類型的任何子類型的對象。這樣我們在選擇返回對象的類時就有了很大的靈活性。這種靈活性的一種應用是,API可以返回對象,同時又不會使它們的類變成公有的。以這種方式隱藏實現類會使API變得非常簡潔。這種方法適合于基于接口的框架(interface-based framework,見第18條),因為在這種框架中,接口為靜態(tài)工廠方法提供了自然返回類型。接口不能有靜態(tài)方法,因此按照慣例,接口Type的靜態(tài)工廠方法被放在一個名為Types的不可實例化的類(見第4條)中?,F在的Collections Framework API比導出32個獨立公有
7、類的那種實現方式要小得多,每種便利實現對應一個類。這不僅僅是指API數量上的減少,也是概念意義上的減少。用戶知道,被返回的對象是由相關的接口精確指定的,所以他們不需要閱讀該實現類的額外類文檔。使用這種靜態(tài)工廠方法時,甚至要求客戶端通過接口來引用被返回的對象,而不是通過它的實現類來引用被返回的對象,一般來說這是一種良好的習慣(見第52條)。公有的靜態(tài)工廠方法所返回的對象的類不僅可以是非公有的,而且該類還可以隨著每次調用而發(fā)生變化,具體取決于靜態(tài)工廠方法的參數值。只要是已聲明的返回類型的子類型,都是允許的。為了提升軟件的可維護性和性能,返回對象的類也可能隨著不同的發(fā)行版本而不同。這兩個實現類的存在
8、對于客戶端來說是不可見的。如果RegularEnumSet不能再給小的枚舉類型提供性能優(yōu)勢,就可以從未來的發(fā)行版本中將它刪除,不會造成不良的影響。同樣地,如果事實證明對性能有好處,也可能在未來的發(fā)行版本中添加第三甚至第四個EnumSet實現??蛻舳擞肋h不知道也不關心他們從工廠方法中得到的對象的類;他們只關心它是EnumSet的某個子類即可。靜態(tài)工廠方法返回的對象所屬的類,在編寫包含該靜態(tài)工廠方法的類時可以不必存在。這種靈活的靜態(tài)工廠方法構成了服務提供者框架(Service Provider Framework)的基礎,例如JDBC(Java數據庫連接, Java Database Connec
9、tivity)API。服務提供者框架是指這樣一個系統(tǒng):多個服務提供者實現一個服務,系統(tǒng)為服務提供者的客戶端提供多個實現,并把他們從多個實現中解耦出來。服務提供者框架中有三個重要的組件:服務接口(Service Interface),這是提供者實現的;提供者注冊API(Provider Registration API),這是系統(tǒng)用來注冊實現,讓客戶端訪問它們的;服務訪問API(Service Access API),是客戶端用來獲取服務的實例的。服務訪問API一般允許但是不要求客戶端指定某種選擇提供者的條件。如果沒有這樣的規(guī)定,API就會返回默認實現的一個實例。服務訪問API是"靈活
10、的靜態(tài)工廠",它構成了服務提供者框架的基礎。服務提供者框架的第四個組件是可選的:服務提供者接口(Service Provider Interface),提供者實現它來創(chuàng)建其服務實現的實例。如果沒有服務提供者接口,實現就按照類名稱注冊,并通過反射方式進行實例化(見第53條)。對于JDBC來說,Connection就是它的服務接口,DriverManager.registerDriver是提供者注冊API,DriverManager.getConnection是服務訪問API,Driver就是服務提供者接口。服務提供者框架模式有著無數種變體。例如,服務訪問API可以利用Adapter模式
11、Gamma95,p.139,返回比提供者需要的更豐富的服務接口。下面是一個簡單的實現,包含一個服務提供者接口和一個默認提供者:/ Service provider framework sketch/ Service interfacepublic interface Service . / Service-specific methods go here/ Service provider interfacepublic interface Provider Service newService();/ Noninstantiable class for service registratio
12、n and accesspublic class Services private Services() / Prevents instantiation (Item 4)/ Maps service names to servicesprivate static final Map providers =new ConcurrentHashMap();public static final String DEFAULT_PROVIDER_NAME = ""/ Provider registration APIpublic static void registerDefau
13、ltProvider(Provider p) registerProvider(DEFAULT_PROVIDER_NAME, p);public static void registerProvider(String name, Provider p)providers.put(name, p);/ Service access APIpublic static Service newInstance() return newInstance(DEFAULT_PROVIDER_NAME);public static Service newInstance(String name) Provid
14、er p = providers.get(name);if (p = null)throw new IllegalArgumentException("No provider registered with name: " + name);return p.newService();靜態(tài)工廠方法的第四大優(yōu)勢在于,在創(chuàng)建參數化類型實例的時候,它們使代碼變得更加簡潔。遺憾的是,在調用參數化類的構造器時,即使類型參數很明顯,也必須指明。這通常要求得接連兩次提供類型參數:Map> m =new HashMap>();隨著類型參數變得越來越長,越來越復雜,這一冗長的說明也
15、很快變得痛苦起來。但是有了靜態(tài)工廠方法,編譯器就可以替你找到類型參數。這被稱作type inference。例如,假設HashMap提供了這個靜態(tài)工廠:public static HashMap newInstance() return new HashMap();你就可以用下面這句簡潔的代碼代替上面這段繁瑣的聲明:Map> m = HashMap.newInstance();總有一天,Java將能夠在構建器調用以及方法調用中執(zhí)行這種type inference,但到發(fā)行版本1.6為止暫時還無法這么做。遺憾的是,到發(fā)行版本1.6為止,標準的集合實現如HashMap并沒有工廠方法,但是可以
16、把這些方法放在你自己的工具類中。更重要的是,可以把這樣的靜態(tài)工廠放在你自己的參數化的類中。靜態(tài)工廠方法的主要缺點在于,類如果不含公有的或者受保護的構造器,就不能被子類化。對于公有的靜態(tài)工廠所返回的非公有類,也同樣如此。例如,要想將Collections Framework中的任何方便的實現類子類化,這是不可能的。但是這樣也許會因禍得福,因為它鼓勵程序員使用復合(composition),而不是繼承(見第16條)。靜態(tài)工廠方法的第二個缺點在于,它們與其他的靜態(tài)方法實際上沒有任何區(qū)別。在API文檔中,它們沒有像構造器那樣在API文檔中明確標識出來,因此,對于提供了靜態(tài)工廠方法而不是構造器的類來說,要想查明如何實例化一個類,這是非常困難的。Javadoc工具總有一天會注意到靜態(tài)工廠方法。同時,你通過在類或者接口注釋中關注靜態(tài)工廠,并遵守標準的命名習慣,也可以縮小這一劣勢。下面是靜態(tài)工廠方法的一些慣用名稱:valueOf-不太嚴格地講,該方法返回的實例與它的參數具有相同的值。這樣的靜態(tài)工廠方法實際上是類型轉換方法。of-valueOf的一種更為簡潔的替代,在EnumSet(見第32條)中使用并流行起來。getInstance-返回的實例是通過方法的參數來描述的,但是不能夠說與參數具有同樣的值。對于Singleton來說,該方法沒有參數,并返回唯
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025項目綠化施工合同
- 新興汽車故障解決方案試題及答案
- 證券投資學教案
- 南京機電職業(yè)技術學院《民族音樂概論1》2023-2024學年第一學期期末試卷
- 浙江省效實中學2024-2025學年高考語文試題3年高考模擬題透析2年模擬試題含解析
- 武漢船舶職業(yè)技術學院《輕松學營銷》2023-2024學年第一學期期末試卷
- 茂名職業(yè)技術學院《行書創(chuàng)作》2023-2024學年第二學期期末試卷
- 湖北師范大學文理學院《網絡技術與應用》2023-2024學年第二學期期末試卷
- 北京電子科技學院《數值計算方法》2023-2024學年第二學期期末試卷
- 2025年廣西桂平市高三下學期質量調研(一模)歷史試題含解析
- 2025-2030羊毛制品行業(yè)市場調研分析及發(fā)展趨勢與投資前景研究報告
- 房建資料員知識培訓課件
- 新零售背景下的電子商務嘗試試題及答案
- 《商務溝通與談判》課件 第二章 商務溝通原理
- 2024年四川內江中考滿分作文《我也有自己的光芒》8
- 深信服aES產品技術白皮書-V1.5
- (高清版)DB11∕T2316-2024重大活動應急預案編制指南
- 小學生航天科技教育課件
- 人工智能機器人研發(fā)合同
- 放射防護知識培訓
- 《社區(qū)智慧養(yǎng)老模式研究的國內外文獻綜述》4200字
評論
0/150
提交評論