不會(huì)這個(gè)技巧,成不了高級(jí)開發(fā)
高級(jí)開發(fā)起碼得會(huì)些高級(jí)技巧吧?那這些高級(jí)技巧從哪里取得呢?
第一種方式肯定是讀書,什么?你沒(méi)那么多時(shí)間?

幸好,我這里幫你開啟了速讀模式,跟著我一起學(xué)習(xí) 《高效Java》系列。
咱們第一站就來(lái)到了: 靜態(tài)工廠方法
1. 什么是靜態(tài)工廠方法?
靜態(tài)工廠方法是一種創(chuàng)建對(duì)象的方式。
這里的靜態(tài)工廠方法,并不是設(shè)計(jì)模式中的工廠模式。
靜態(tài)工廠方法僅僅是類的一個(gè)普通的靜態(tài)方法,它的最終效果等同于構(gòu)造器。
說(shuō)了這么多,給你舉個(gè)例子就明白了。
Integer?integer?=?Integer.valueOf("1");
Boolean?aBoolean?=?Boolean.valueOf(true);
Calendar?calendar?=?Calendar.getInstance();
上面的例子中 valueOf 和 getInstance 方法就被稱為 靜態(tài)工廠方法。
2. 靜態(tài)工廠方法優(yōu)勢(shì)
那么為什么鼓勵(lì)用靜態(tài)工廠方法來(lái)創(chuàng)造對(duì)象,而不是鼓勵(lì)使用構(gòu)造器呢?
原因有如下幾點(diǎn):
靜態(tài)工廠方法擁有名稱,而構(gòu)造器沒(méi)有
不必在每次調(diào)用靜態(tài)工廠方法時(shí)都創(chuàng)建一個(gè)對(duì)象
可以返回當(dāng)前類的任何子類型對(duì)象
減少使用者出錯(cuò)的概率
下面我們來(lái)逐一了解這些優(yōu)點(diǎn):
2.1 靜態(tài)工廠方法擁有名稱,而構(gòu)造器沒(méi)有
因?yàn)闃?gòu)造器的本身并沒(méi)有確切的描述被返回的對(duì)象,而靜態(tài)工廠方法因?yàn)橛蟹椒?,所以他能夠更為清楚的描述將被返回的?duì)象。尤其是擁有多個(gè)不同參數(shù)的構(gòu)造方法,在選擇構(gòu)造方法的時(shí)候,會(huì)讓人有些迷惑,而靜態(tài)工廠方法則更加清楚明了。
//Date類
Date?date0?=?new?Date();
Date?date1?=?new?Date(2022L);
Date?date2?=?new?Date("2022");
Date?date3?=?new?Date(2022,3,20);
Date?date4?=?new?Date(2022,3,20,18,30,59);
//?LocalDate類
public?static?LocalDate?now(){}
public?static?LocalDate?ofEpochDay(long?epochDay){}
public?static?LocalDate?of(int?year,?Month?month,?int?dayOfMonth)?{}
★看下這么多不同參數(shù)的構(gòu)造方法,如果不去了解Date,懵不懵? 再看看 Java8 中的LocalDate類。
”
2.2 不必在每次調(diào)用靜態(tài)工廠方法時(shí)都創(chuàng)建一個(gè)對(duì)象
構(gòu)造器每次調(diào)用的時(shí)候都會(huì)創(chuàng)建一個(gè)新的對(duì)象,而使用靜態(tài)工廠方法則可以不必每次都創(chuàng)建新的對(duì)象,我們可以提前創(chuàng)建好對(duì)象或重用已有的對(duì)象,以達(dá)到提升性能的目的。
來(lái)我給你們舉個(gè)例子:
1、Integer 類中的 valueOf 方法,當(dāng)數(shù)值在 -128 ~ 127之間時(shí),是不會(huì)創(chuàng)建新的Integer類的,而是從緩存中取出。
public?static?Integer?valueOf(int?i)?{
????if?(i?>=?IntegerCache.low?&&?i?<=?IntegerCache.high)
??????????return?IntegerCache.cache[i?+?(-IntegerCache.low)];
??????return?new?Integer(i);
}
2、Boolean 類中的 valueOf 方法,直接取出提前創(chuàng)建好的靜態(tài)常量返回,也沒(méi)有創(chuàng)建新的對(duì)象。
public?final?class?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);
????}
}
2.3 可以返回原類型的任何子類型對(duì)象
這里牽涉到最基礎(chǔ)的多態(tài):
向上轉(zhuǎn)型:多態(tài)本身就是向上轉(zhuǎn)型過(guò)的過(guò)程
使用格式:父類類型 變量名=new 子類類型();
還有就是設(shè)計(jì)模式六大原則中的<里氏替換原則>:
- 任何使用父類的地方都能替換成子類來(lái)使用。
public?class?Test?{
?//靜態(tài)工廠方法,返回Test的子類型T1
????public?static?Test?valueOf(){
????????return?new?T1();
????}
????private?static?class?T1?extends?Test{}
}
雖然可以這樣用,但是不建議這樣使用,因?yàn)檫@樣不利于解耦,父類最好不要依賴于子類。
推薦的做法是:像 Collections 類一樣,它像一個(gè)工具類,它提供了許多靜態(tài)工廠方法,你去看會(huì)發(fā)現(xiàn)靜態(tài)工廠方法返回的并不是確定的類型,而是List接口的一些子類,這些子類被作為私有類定義在Collections 中,我們無(wú)法直接構(gòu)造這些類,但卻可以通過(guò)靜態(tài)工廠方法使用它。
這樣做的目的是精減API的數(shù)量,對(duì)客戶端來(lái)說(shuō)也是一種減壓。我們有時(shí)不必知道返回的類是什么,但我們可以像我們熟知的接口一樣使用它。
//?SingletonList?是私有的,實(shí)現(xiàn)List接口的類
public?static??List?singletonList(T?o)?{
?????return?new?SingletonList<>(o);
}
//?EmptyList?是私有的,實(shí)現(xiàn)List接口的類
public?static?final??List?emptyList()?{
?????return?(List)?EMPTY_LIST;
}
2.4 減少使用者出錯(cuò)的概率
先看下例子:
class?Run?{
????public?static?final?int?RUNNING?=?1;
????public?static?final?int?STOP?=?2;
????protected?int?state;
????public?Run(int?state)?{
????????this.state?=?state;
????}
????public?void?process(){
????????//?if?RUNNING?/?STOP
????}
}
上面例子中,我只想對(duì) RUNNING / STOP 兩種狀態(tài)處理,但我卻無(wú)法控制使用者的行為,比如他可以這樣調(diào)用:new Run(4)
這種情況怎么辦呢?
class?Run?{
????public?static?final?int?RUNNING?=?1;
????public?static?final?int?STOP?=?2;
????protected?int?state;
????//私有構(gòu)造方法外部無(wú)法調(diào)用
????private?Run(int?state)?{
????????this.state?=?state;
????}
????public?static?Run?running(){
????????return?new?Run(RUNNING);
????}
????public?static?Run?stop(){
????????return?new?Run(STOP);
????}
????public?void?process(){
????????//?if?RUNNING?/?STOP
????}
}
經(jīng)過(guò)這樣改造后,我們嚴(yán)格控制了取值范圍,使用者出錯(cuò)的機(jī)會(huì)就大大減少了。
3. 總結(jié)
作為類的提供者,我們要盡量確保自身性能好,具有靈活性,讓使用者使用起來(lái)更容易,更不容易出錯(cuò)。
恰恰靜態(tài)工廠方法可以讓我們做到這些,所有建議創(chuàng)建對(duì)象的時(shí)候優(yōu)先考慮使用靜態(tài)工廠方法。
整理了許多學(xué)習(xí)資料,牽涉 Spring、mybatis、redis、分布式、面試、簡(jiǎn)歷等。
如需要,可在公眾號(hào)中回復(fù):資料???即可獲?。?/span>

