[英]Java static methods pros & cons
我之前沒有使用過很多靜態方法,但最近我傾向於使用更多靜態方法。 例如,如果我想在類中設置一個布爾標志,或者需要在一個類中設置一個布爾標志,而不需要通過類傳遞實際的對象。
例如:
public class MainLoop
{
private static volatile boolean finished = false;
public void run()
{
while ( !finished )
{
// Do stuff
}
}
// Can be used to shut the application down from other classes, without having the actual object
public static void endApplication()
{
MainLoop.finished = true;
}
}
這是我應該避免的嗎? 傳遞一個對象以便使用對象方法更好嗎? 布爾finished
現在是否計為全局,或者它是否同樣安全?
是的,傳遞物體更好。 使用單例或靜態方法使OO編程看起來像過程編程。 單例有點好,因為你至少可以使它實現接口或擴展抽象類,但它通常是一種設計氣味。
將實例方法與靜態變量混合就像你正在做的那樣更令人困惑:你可以讓幾個對象循環,但你會立刻停止它們,因為它們都會在靜態變量發生變化時停止。
這是我應該避免的嗎?
一般來說,是的。 靜力學代表全球狀態。 全局狀態難以推理,難以單獨測試,並且通常具有更高的線程安全性要求。
如果我想測試某個狀態下對象會發生什么,我可以創建該對象,將其置於該狀態,執行我的測試,並讓它被垃圾收集。
如果我想測試全局狀態會發生什么,我需要確保在測試結束時(或者可能在每次測試開始時)重置所有狀態。 如果我不小心這樣做,測試現在會相互干擾。
當然,如果靜態方法不需要影響任何狀態 - 即如果它是純粹的 - 那么它會變得更好一些。 那時你所失去的就是能夠替換那個方法實現,例如在測試調用它的東西時。
在這種情況下使用靜態變量的一個問題是,如果您創建兩個(或更多)MainLoop實例,編寫看起來像它的代碼只關閉其中一個實例,實際上將關閉它們:
MainLoop mainLoop1 = new MainLoop();
MainLoop mainLoop2 = new MainLoop();
new Thread(mainLoop1).start();
new Thread(mainLoop2).start();
mainLoop1.finished = true; // static variable also shuts down mainLoop2
這只是選擇不使用靜態變量的原因之一(在眾多中)。 即使您的程序今天只創建了一個MainLoop,但未來您可能有理由創建其中許多:用於單元測試,或實現一個很酷的新功能。
您可能會想“如果發生這種情況,我只會重構程序以使用成員變量而不是靜態變量。” 但是,預先支付成本通常更有效,並且從一開始就將模塊化設計融入到程序中。
毫無疑問,靜態通常會使快速而骯臟的程序更容易編寫。 但是對於您打算在未來幾年內測試,維護,增長,共享和使用的重要/復雜代碼,通常建議使用靜態變量。
在一般情況下,通過使finished
靜態像您所創建的情況下,只能有你的一個實例MainLoop
執行的類run
在任何一個時間。 如果有多個實例,則設置finished
將結束它們 - 而不是通常所需的。
但是,在這種特殊情況下,您希望“結束應用程序”,可能意味着您希望結束MainLoop
所有實例,這種方法可能是合理的。
然而,在這種方法可以值得的情況下,數量很少,一個“干凈”的方式來處理這種情況將保持static
情況下的列表,並在列表中工作,設置實例變量finished
的每個實例。 這允許您也結束單個實例,為您提供現有實例的自然計數等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.