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

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

EffectiveJava讀書筆記(一):使用靜態(tài)工廠方法代替構(gòu)造器

2019-11-14 15:30:41
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

這是Effective java第2章提出的第一條建議:

考慮用靜態(tài)工廠方法代替構(gòu)造器

此處的靜態(tài)工廠方法并不是設(shè)計(jì)模式,主要指static修飾的靜態(tài)方法,關(guān)于static的說(shuō)明可以參考之前的博文《java中final與static的使用場(chǎng)景總結(jié)》。

什么是靜態(tài)工廠方法?

可以參考書中的例子(摘自JDK1.7 java.lang.Boolean)

public final class Boolean implements java.io.Serializable,        Comparable<Boolean> {    public static final Boolean TRUE = new Boolean(true);    public static final Boolean FALSE = new Boolean(false);    public static Boolean valueOf(boolean b) {        return (b ? TRUE : FALSE);    }}

如果需要獲取一個(gè)Boolean對(duì)象,常規(guī)的方法是new Boolean(true),但是也可以如上圖所示Boolean.valueOf(true),這便是靜態(tài)工廠方法。

靜態(tài)工廠方法的優(yōu)勢(shì)

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

使用構(gòu)造函數(shù)構(gòu)造對(duì)象時(shí),我們需要通過(guò)文檔仔細(xì)比對(duì)傳遞什么樣的參數(shù)能夠構(gòu)造什么樣的對(duì)象。但是靜態(tài)工廠方法可以使用不同的方法名字使得其構(gòu)造的對(duì)象更加明晰。我們完全可以通過(guò)方法名明白構(gòu)造了什么樣的對(duì)象。

例如下面的例子(摘自JDK1.7 java.math.BigInteger)

public class BigInteger extends Number implements Comparable<BigInteger> {    /**     * Returns a positive BigInteger that is PRobably prime, with the     * specified bitLength. The probability that a BigInteger returned     * by this method is composite does not exceed 2<sup>-100</sup>.     */    public static BigInteger probablePrime(int bitLength, Random rnd) {       // XXX    }}

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

我們調(diào)用靜態(tài)工廠方法返回的可能是緩存的一個(gè)對(duì)象,而不是新對(duì)象。可以進(jìn)行重復(fù)利用,從而避免創(chuàng)建不必要的重復(fù)對(duì)象。 
如果程序經(jīng)常請(qǐng)求創(chuàng)建相同的對(duì)象,并且創(chuàng)建的代價(jià)很高,則靜態(tài)工廠方法可以極大地提升性能。 
前面提到的Boolean.valueOf(boolean)便說(shuō)明了這項(xiàng)技術(shù)。

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

我們?cè)谶x擇返回對(duì)象的類時(shí)有了更大的靈活性。參見(jiàn)java.util.EnumSet,其本身被abstract修飾,無(wú)法直接調(diào)用其構(gòu)造函數(shù)。但可以調(diào)用其靜態(tài)方法noneOf來(lái)創(chuàng)建對(duì)象,并且根據(jù)參數(shù)返回合適的對(duì)象。

public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>    implements Cloneable, java.io.Serializable {    EnumSet(Class<E>elementType, Enum[] universe) {    }    //RegularEnumSet與JumboEnumSet均為EnumSet的子類    public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {        if (universe.length <= 64)            return new RegularEnumSet<>(elementType, universe);        else            return new JumboEnumSet<>(elementType, universe);    }}

第四大優(yōu)勢(shì)在于,創(chuàng)建參數(shù)化類型實(shí)例的時(shí)候,可以使代碼變得更加簡(jiǎn)潔。

例如對(duì)于HashMap的實(shí)例化:

//常規(guī)實(shí)例化方式Map<String, List<String>> m =    new HashMap<String, List<String>>();public static <K, V> HashMap<K, V> newInstance() {    return new HashMap<K, V>();}//使用靜態(tài)工廠方法實(shí)例化,簡(jiǎn)化繁瑣的聲明Map<String, List<String>> m = HashMap.newInstance();

靜態(tài)工廠方法的劣勢(shì)

類如果不含公有的或受保護(hù)的構(gòu)造器,就不能被實(shí)例化。

如果我們?cè)陬愔袑?gòu)造函數(shù)設(shè)為private,只提供靜態(tài)工廠方法來(lái)構(gòu)建對(duì)象,那么我們將不能通過(guò)繼承擴(kuò)展該類。 
但是這也會(huì)鼓勵(lì)我們使用復(fù)合而不是繼承來(lái)擴(kuò)展類。

它們與其他的靜態(tài)方法實(shí)際上沒(méi)有任何區(qū)別。

在API文檔中,構(gòu)建對(duì)象的靜態(tài)工廠方法并沒(méi)有像構(gòu)造器那樣明確標(biāo)識(shí)出來(lái),不能和其他靜態(tài)方法很方便地區(qū)分開(kāi)來(lái)。 
如果類中只提供靜態(tài)工廠方法而不是構(gòu)造器,要想查明如何實(shí)例化一個(gè)類將會(huì)變得困難。 
我們可以通過(guò)遵循靜態(tài)工廠方法的命名規(guī)范來(lái)彌補(bǔ)這一劣勢(shì):

  • valueOf - 返回的實(shí)例與它的參數(shù)具有相同的值,一般作為類型轉(zhuǎn)換使用,例如Boolean.valueOf(boolean)
  • of - valueOf的更為簡(jiǎn)潔的替代。
  • getInstance - 返回的實(shí)例通過(guò)方法的參數(shù)來(lái)描述,但不能說(shuō)與參數(shù)具有同樣的值。對(duì)于Singleton來(lái)說(shuō),使用無(wú)參getInstance,返回唯一的實(shí)例。
  • newInstance - 像getInstance一樣,但其能夠確保每次都返回新的對(duì)象。
  • getType - 像getInstance一樣,但此方法返回的對(duì)象是另一個(gè)不同的類。
  • newType - 像getType一樣,但每次返回一個(gè)新對(duì)象。

總而言之,靜態(tài)工廠方法和公有構(gòu)造器具有各自的用處,但靜態(tài)工廠方法通常更加合適,所以我們應(yīng)該優(yōu)先考慮靜態(tài)工廠方法。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 阿克苏市| 收藏| 建始县| 奉节县| 光泽县| 外汇| 武陟县| 孝感市| 古丈县| 蓝山县| 乌拉特前旗| 凤山市| 龙里县| 抚顺市| 神农架林区| 永兴县| 娄烦县| 称多县| 闸北区| 株洲县| 砚山县| 句容市| 宣恩县| 高要市| 荆门市| 太仓市| 华容县| 鄂托克旗| 东辽县| 图片| 博罗县| 扶风县| 鞍山市| 长宁县| 新疆| 紫云| 沁水县| 临潭县| 久治县| 图木舒克市| 贵州省|