2010-10-18 37 views
12

如何,我們應該在哪裏使用static修飾符爲:在Java中如何以及在何處使用靜態修飾符?

領域和
2.方法?

對於java.lang.Mathexample,田野方法,如ABS(),ATAN(),COS()等都是靜態的,即它們可以作爲訪問:Math.abs()

但爲什麼它是一個很好的做法?我不保持靜態,並創建一個類的對象並訪問它,反正我可以,我只會得到一個警告,你試圖以非靜態方式訪問一個靜態方法(正如@duffymo所指出的,而不是Math類的情況)。

UPDATE 1:

所以,實用方法,應該是靜態的,即,其工作是僅依賴於所述方法的參數。因此,例如,方法updateString(String inputQuery, String highlightDoc)應該是this question中的靜態方法嗎?

回答

20

您可以將'static'方法或字段視爲在類定義之外聲明。換句話說,

  1. 只有一個「複製」的靜態字段/方法。
  2. 靜態字段/方法不能訪問非靜態字段/方法。

有幾種情況下,你會想要做一些靜態的東西。

一個字段的規範示例是創建一個靜態整數字段,該字段保持一個類的所有實例(對象)的計數。另外,單例對象也通常使用靜態修飾符。

同樣,可以使用靜態方法執行所有必需的依賴項作爲參數傳遞給方法的「實用程序」作業 - 您不能在靜態方法內引用「this」關鍵字。

在C#中,你也可以有靜態類,正如你可能已經猜到,只包含靜態成員:

public static class MyContainer 
{ 
    private static int _myStatic; 

    public static void PrintMe(string someString) 
    { 
     Console.Out.WriteLine(someString); 
     _myStatic++; 
    } 

    public static int PrintedInstances() 
    { 
     return _myStatic; 
    } 
} 
+0

請檢查我的更新。你可以給我一些關於我在問題中發佈的示例方法的信息。這也是一種實用方法。 – zengr 2010-10-18 22:48:33

+0

@zengr:是的,我會讓這個方法變成靜態的。你可以想象一下,例如一個StringHelper類,它封裝了所有你的應用程序特定的字符串操作操作(比如那個方法執行的操作)。事實上,如果不引用'this'關鍵字,我會使_any_方法成爲靜態的;不需要在每個對象上創建此方法的副本,這樣就更清晰易讀,並且有利於整體設計IMO的清晰度。 – Alex 2010-10-18 23:07:21

1

通常,當該方法僅依賴於函數的參數,而不是的內部狀態對象它是一個靜態方法(唯一的例外是singletone)。我無法想象靜態字段的真正用途(它們與應避免的全局變量相同)。
和你的例子一樣,數學函數只依賴於參數。

+1

靜態修飾符有完全合法的用法,例如我的答案中列出的用法。 – Alex 2010-10-18 22:45:08

+0

「它們與應該避免的全局變量相同」 - 如果它們是最終的,則不是這樣;這些通常顯示爲類常量。 – 2010-10-18 22:46:27

+0

@alex我沒有想過這件事。我猜靜態字段的使用主要取決於你的編程方式,並且在使用它們的時候可能會有非常好的情況(並且它們不是以任何方式單獨出現的)。只是因爲我還沒有見到它們並不意味着他們存在或者是不好的:)對於我自己的利益,你能解釋我爲什麼你想知道一個對象的實例的總數,但它沒有提及? – Fge 2010-10-18 22:50:48

0

您不能實例化java.lang.Math的實例;沒有公共構造函數。

試試:

public class MathTest 
{ 
    public static void main(String [] args) 
    { 
     Math math = new Math(); 

     System.out.println("math.sqrt(2) = " + math.sqrt(2)); 
    } 
} 

這裏就是你會得到什麼:

C:\Documents and Settings\Michael\My Documents\MathTest.java:5: Math() has private access in java.lang.Math 
     Math math = new Math(); 
        ^
1 error 

Tool completed with exit code 1 
+0

糟糕,錯過了它。但總的來說,如果一個方法是靜態的,我們可以使用一個對象來訪問它。那麼,通過使用靜態內存的效率在哪裏呢? – zengr 2010-10-18 22:49:25

+1

這不是記憶效率的問題;這是關於班級設計師的意圖。 – duffymo 2010-10-19 00:50:38

1

對於一個領域,你應該保持靜態,如果你想給定類的所有實例來訪問它值。例如,如果我有

public static int age = 25; 

然後,任何類的實例都可以獲取或設置所有指向相同值的age的值。如果你確實做了一些靜態的事情,那麼你就會冒兩個實例覆蓋其他值並可能導致問題的風險。

創建靜態方法的原因主要是針對實用程序功能,其中傳遞了該方法的所有必需數據,並且您不希望在每次要調用該方法時都想要創建類的實例方法。

8

靜態使用更少的內存,因爲每個類加載器只存在一次。

靜態方法可能會節省一些時間,因爲您不必先創建對象,以便調用函數。你可以/應該使用靜態方法,當他們站在幾乎自己的位置時(例如Math.abs(X) - 實際上沒有對象需要這個函數)。基本上它是一個方便的東西(至少就我看到的而言 - 其他人可能會也會不同意:P)

靜態字段應該謹慎使用。有相當多的模式需要靜態字段...但基本的第一個:

一個靜態字段只存在一次。所以,如果你有一個簡單的類(有點僞代碼):

class Simple { 
static int a; 
int b; 
} 

你現在讓使用對象:

Simple myA = new Simple(); 
Simple myB = new Simple(); 
myA.a = 1; 
myA.b = 2; 
myB.a = 3; 
myB.b = 4; 
System.out.println(myA.a + myA.b + myB.a + myB.b); 

你會得到3234 - 因爲通過設置myB.a你實際上覆蓋myA.a以及因爲a是靜態的。它存在於內存中的一個地方。

您通常希望避免這種情況,因爲可能會發生奇怪的事情。但是,如果你的谷歌例如工廠模式你會看到,這種行爲實際上是非常有用的用途。

希望清除它一點點。

+1

靜態字段每個類加載器存在一次,而不是每個JVM一次。 – user82928 2014-11-22 23:25:34

2

試着看看這篇文章,它也給出了一些什麼時候以及何時不使用靜態和最終修飾符的例子。

以上大多數帖子都是類似的,但這篇文章可能會提供一些其他的見解。
When to use Static Modifiers

相關問題