簡體   English   中英

Java靜態方法的優點和缺點

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM