條款4:通過私有構(gòu)造?法強制禁?類的實例化
有時依啰,你想要編寫?個只包含?組靜態(tài)?法和靜態(tài)字段的類油狂。這種類有?個不太好的名聲站超,因為有些?會濫?他們斤程,不從對象的?度來思考角寸,?是堅信他們的想法是正確?誤的。他們可?于將針對原?值或是數(shù)組的?法劃分到?起忿墅,?如說java.lang.Math
或是java.util.Arrays
扁藕;還可以將靜態(tài)?法劃分到?起,包括??(條款1
)疚脐,?于實現(xiàn)了某個接?的對象亿柑,?如說java.util.Collections
(從Java 8開始,如果想要??修改棍弄,那么你還可以將這類?法放到接?中)望薄。最后,還可以將針對終態(tài)類的?法劃分到?起呼畸,因為你?法再將他們放到?類中了痕支。
這種輔助類在設(shè)計時是不希望被實例化的:實例本身是毫?意義的。不過蛮原,如果沒有顯式指定構(gòu)造?法卧须,那么編譯器就會提供?個公有、?參的默認構(gòu)造?法。對于?戶來說花嘶,該構(gòu)造?法很難與其他構(gòu)造?法區(qū)分開來笋籽。我們常常會在已發(fā)布的APIs
中看到?意中被實例化的類。
通過將?個類設(shè)置為抽象類來強制禁?類的實例化是?不通的察绷。類可以被?類化干签,??類是可以實例化的。此外拆撼,這么做會對?戶產(chǎn)?誤導容劳,讓?戶誤以為這個類的設(shè)計?的是為了繼承(條款19
)。然?闸度,有?種簡單的?式可以確保類?法被實例化竭贩。如果?個類中沒有顯式指定構(gòu)造?法,那么會?成?個默認構(gòu)造?法莺禁,因此通過在類中增加?個私有構(gòu)造?法就可以確保類?法被實例化了留量。
//不可實例化的實用程序類
public class UtilityClass {
//取消不可實例化的默認構(gòu)造函數(shù)
private UtilityClass(){
throw new AssertionError();
}
}
由于顯式構(gòu)造?法是私有的,因此它在類的外部是?法被訪問到的哟冬。AssertionError
并不是?定要加的楼熄,不過如果在類的內(nèi)部不??被調(diào)?的話,它會提供?種保證浩峡。它可以確保在任何情況下類都是絕對?法被實例化的可岂。這種?式有點?違背直覺,因為提供構(gòu)造?法的?的僅僅是為了??不能被調(diào)?翰灾。更好的做法則是加上?些注釋說明缕粹,正如上述代碼所做的那樣。
這種做法的?個副作?則是類也?法被?類化了纸淮。所有構(gòu)造?法都得顯式或隱式調(diào)??類構(gòu)造?法平斩,??類在這種情況下沒有可訪問到的?類構(gòu)造?法去調(diào)?。