它不太面向?qū)ο螅?/strong>有些人認為靜力學(xué)是“邪惡”的原因之一是它們與面向?qū)ο蠓妒?/trans>。特別是,它違反了數(shù)據(jù)封裝在對象(可以擴展、信息隱藏等)中的原則。靜力學(xué),以你描述的方式使用它們,本質(zhì)上是將它們作為一個全局變量來使用,以避免處理像范圍這樣的問題。然而,全局變量是過程或命令式編程范式的定義特征之一,而不是面向?qū)ο蟠a的“好”特性。這并不是說過程范式是糟糕的,但我得到的印象是,您的主管希望您編寫“良好的面向?qū)ο蟮拇a”,并且您確實希望編寫“良好的過程代碼”。
當(dāng)您開始使用靜力學(xué)時,Java中有許多問題并不總是顯而易見的。例如,如果程序的兩個副本運行在同一個VM中,那么它們會不會SHRE靜態(tài)變量的值和彼此狀態(tài)的混亂?或者當(dāng)您擴展類時,可以覆蓋靜態(tài)成員嗎?您的VM是否因為有大量的靜力學(xué)而耗盡內(nèi)存,并且無法為其他所需的實例對象回收內(nèi)存?
對象生命周期:此外,靜力學(xué)的生命周期與程序的整個運行時相匹配。這意味著,即使使用完類,也不能垃圾收集所有這些靜態(tài)變量的內(nèi)存。例如,如果您將變量設(shè)置為非靜態(tài)變量,并且在main()函數(shù)中創(chuàng)建了類的單個實例,然后要求類執(zhí)行特定函數(shù)10,000次,一旦完成這10,000次調(diào)用,并且刪除對單個實例的引用,則可以垃圾收集和重用所有靜態(tài)變量。
防止某些重復(fù)使用:此外,靜態(tài)方法不能用于實現(xiàn)接口,因此靜態(tài)方法可以阻止某些面向?qū)ο蟮奶匦钥捎谩?/trans>
其他備選方案:如果效率是您最關(guān)心的問題,那么可能還有其他更好的方法來解決速度問題,而不是僅僅考慮調(diào)用通常比創(chuàng)建更快的優(yōu)點。考慮是否在任何地方都需要瞬態(tài)或易失性修飾符。為了保持內(nèi)聯(lián)的能力,方法可以標記為Final而不是靜態(tài)的。方法參數(shù)和其他變量可以標記為Final,以允許基于可以更改這些變量的假設(shè)進行某些編譯器優(yōu)化??梢远啻沃赜脤嵗龑ο?,而不是每次創(chuàng)建新實例。可能會有復(fù)雜優(yōu)化開關(guān),應(yīng)該打開的應(yīng)用程序在一般情況下。也許,設(shè)計應(yīng)該設(shè)置,這樣就可以運行10,000次多線程,并利用多處理器內(nèi)核。如果可移植性不是一個問題,也許一個本地的方法會讓你比你的靜力學(xué)更快。
如果由于某種原因不希望一個對象的多個副本,則單例設(shè)計模式,與靜態(tài)對象相比具有優(yōu)勢,例如線程安全(假定您的單例代碼編寫得很好)、允許延遲初始化、確保對象在使用時被正確初始化、子類化、測試和重構(gòu)代碼方面的優(yōu)勢,更不用說,如果您在某一時刻改變了只想要一個對象實例的想法,那么刪除代碼以防止重復(fù)實例要比重構(gòu)所有靜態(tài)變量代碼以使用實例變量容易得多。我以前不得不這樣做,這并不有趣,最后你不得不編輯更多的類,這就增加了引入新bug的風(fēng)險…所以最好在第一次設(shè)置“正確”的東西,即使它似乎有它的缺點。對我來說,如果你決定在路上需要多個副本的話,你所需要的返工可能是盡可能不經(jīng)常使用靜力學(xué)的最有說服力的原因之一。因此,我也不同意你所說的靜力學(xué)減少相互依賴的說法,我認為,如果你有很多可以直接訪問的靜力學(xué),而不是一個“知道如何在自己身上做某事”的對象,你最終會得到更多耦合的代碼。