2010-04-15 49 views
80

我已經被告知了它的幾個定義,看着維基百科,但作爲Java的初學者,我仍然不確定它的含義。任何流利的Java和白癡?從外行的角度來看,Java中'靜態'是什麼意思?

+2

哪個靜態?有很多靜態信息(例如http://mindprod.com/jgloss/static.html的非詳盡列表)。 – kennytm 2010-04-15 21:52:10

+0

@Philip Strong:static是一個Java idiosynchrasy,而且陪審團仍然決定'static'是否在面向對象的語言中佔有一席之地;) – SyntaxT3rr0r 2010-04-15 22:16:45

回答

212

靜態意味着標記爲的變量或方法在類級別可用。換句話說,你不需要創建一個類的實例來訪問它。

public class Foo { 
    public static void doStuff(){ 
     // does stuff 
    } 
} 

所以,而不是創建美孚的一個實例,然後調用doStuff這樣的:

Foo f = new Foo(); 
f.doStuff(); 

你可以直接調用該方法對類,像這樣:

Foo.doStuff(); 
+5

這很有道理!謝謝。 – 2010-04-15 21:53:47

+14

還應該提到,靜態字段由類的所有實例共享,因此所有實例都看到相同的值。 – 2010-04-15 21:56:22

+8

@彼得:它不是「被所有實例共享」,因爲它只屬於一個類,因爲它屬於類。一些'public static'對每個人來說都是免費的,而不是嚴格地在實例之間共享。 – polygenelubricants 2010-04-16 03:52:19

34

非常普通的用語是課堂上的模具,而對象是用模具製作的複製品。靜態屬於模具,可以直接訪問而無需製作任何副本,因此以上示例爲

3

除了@inkedmn指出的內容,靜態成員在類級別。因此,該成員由JVM一次加載到內存中(該類加載時)。也就是說,沒有爲其所屬的類的實例加載的靜態成員的實例n

6

另一個很好的例子是何時使用靜態屬性和操作時想要應用Singleton設計模式。簡而言之,Singleton設計模式可以確保在系統的整個生命週期內建立一個特定類的唯一對象。爲了確保只構造一個對象,Singleton模式的典型實現保持對單個允許對象實例的內部靜態引用,並且使用static操作來控制對該實例的訪問

-4

上述點是正確的並且我想要添加一些關於Static關鍵字的更重要的點。

內部什麼,當你使用靜態關鍵字將在常駐內存(即在堆內存),我們知道,有兩種類型的存儲他們堆棧存儲器存儲發生(臨時存儲)和堆內存(永久內存),所以如果你沒有使用靜態關鍵字,然後將存儲在臨時內存中是在堆棧內存(或者你可以稱它爲易失性內存)。

所以你會懷疑這是什麼使用權?

例如:靜態INT A = 10;(1個計劃)

剛纔我說,如果你使用static關鍵字爲變量方法將在永久記憶合適的店面。

所以我在其他程序中聲明與關鍵字靜態相同的變量具有不同的值。

例如:靜態INT A = 20;(2程序)

的變量 'a' 是由程序存儲在堆存儲器1。同樣靜態變量 'a' 在程序中找到2那時它不會再在堆內存中創建'a'變量,而不是隻取代10的值到20

如果你沒有聲明'a'作爲靜態變量,通常它會再次創建棧存儲器(臨時存儲器)中的變量'a'。

總的來說,我可以說的是,如果我們使用static關鍵字
  1.我們可以節省內存
  2.我們能避免重複
  3.No需要按順序訪問靜態變量創建對象的在類名的幫助下,您可以訪問它。

+0

-1,問題在於尋找初學者的東西。這種永久的,暫時的和不穩定的談話並不會被初學者理解,反正事實上是不正確的。 – Martin 2014-09-12 07:19:51

+0

他們不是一個大老闆的老闆..他們可以明白,他們必須知道我爲什麼提到他們的實際區別。 – sushanth 2014-09-12 07:46:52

+3

它們不是什麼大的詞,但是你聲稱的在Java中是完全錯誤的,並且無論如何都與這個問題無關。 – Martin 2014-09-12 08:07:39

10

靜態關鍵字可以在Java中以幾種不同的方式使用,並且在幾乎所有情況下它都是一個修飾符,這意味着它正在修改的東西可用,不需要封閉對象實例

Java是一種面向對象的語言,默認情況下,您編寫的大多數代碼都需要要使用的對象實例。

public class SomeObject { 
    public int someField; 
    public void someMethod() { }; 
    public Class SomeInnerClass { }; 
} 

爲了使用someField,的someMethod,或SomeInnerClass 我必須首先創建SomeObject的一個實例。

public class SomeOtherObject { 
    public void doSomeStuff() { 
     SomeObject anInstance = new SomeObject(); 
     anInstance.someField = 7; 
     anInstance.someMethod(); 
     //Non-static inner classes are usually not created outside of the 
     //class instance so you don't normally see this syntax 
     SomeInnerClass blah = anInstance.new SomeInnerClass(); 
    } 
} 

如果我宣佈這些事情靜態那麼他們不需要類實例

public class SomeObjectWithStaticStuff { 
    public static int someField; 
    public static void someMethod() { }; 
    public static Class SomeInnerClass { }; 
} 

public class SomeOtherObject { 
    public void doSomeStuff() { 
     SomeObjectWithStaticStuff.someField = 7; 
     SomeObjectWithStaticStuff.someMethod(); 
     SomeObjectWithStaticStuff.SomeInnerClass blah = new SomeObjectWithStaticStuff.SomeInnerClass(); 
     //Or you can also do this if your imports are correct 
     SomeInnerClass blah2 = new SomeInnerClass(); 
    } 
} 

聲明靜態有一些含義。

首先,在整個應用程序中只能有一個靜態字段的值爲

public class SomeOtherObject { 
    public void doSomeStuff() { 
     //Two objects, two different values 
     SomeObject instanceOne = new SomeObject(); 
     SomeObject instanceTwo = new SomeObject(); 
     instanceOne.someField = 7; 
     instanceTwo.someField = 10; 
     //Static object, only ever one value 
     SomeObjectWithStaticStuff.someField = 7; 
     SomeObjectWithStaticStuff.someField = 10; //Redefines the above set 
    } 
} 

的第二個問題是,靜態方法和內部類不能訪問字段在包圍對象(因爲沒有一個)。

public class SomeObjectWithStaticStuff { 
    private int nonStaticField; 
    private void nonStaticMethod() { }; 

    public static void someStaticMethod() { 
     nonStaticField = 7; //Not allowed 
     this.nonStaticField = 7; //Not allowed, can never use *this* in static 
     nonStaticMethod(); //Not allowed 
     super.someSuperMethod(); //Not allowed, can never use *super* in static 
    } 

    public static class SomeStaticInnerClass { 

     public void doStuff() { 
      someStaticField = 7; //Not allowed 
      nonStaticMethod(); //Not allowed 
      someStaticMethod(); //This is ok 
     } 

    } 
} 

static關鍵字還可以應用於內部接口,註釋和枚舉。

public class SomeObject Public static interface SomeInterface {}; public static @interface SomeAnnotation {}; public static enum SomeEnum {}; }

在所有這些情況下,關鍵字是多餘的,並且沒有任何作用。接口,註釋和枚舉默認是靜態的,因爲它們從來沒有與內部類的關係。

這只是描述了他們的關鍵字。它沒有描述使用關鍵字是否是一個壞主意。這可以在其他問題中得到更詳細的介紹,如Is using a lot of static methods a bad thing?

關鍵字static也有一些不太常用的用法。有靜態導入可以讓你使用不合格的靜態類型(包括接口,註釋和枚舉,而不是冗餘地標記爲靜態)。

//SomeStaticThing.java 
public class SomeStaticThing { 
    public static int StaticCounterOne = 0; 
} 

//SomeOtherStaticThing.java 
public class SomeOtherStaticThing { 
    public static int StaticCounterTwo = 0; 
} 

//SomeOtherClass.java 
import static some.package.SomeStaticThing.*; 
import some.package.SomeOtherStaticThing.*; 

public class SomeOtherClass { 
    public void doStuff() { 
     StaticCounterOne++; //Ok 
     StaticCounterTwo++; //Not ok 
     SomeOtherStaticThing.StaticCounterTwo++; //Ok 
    } 
} 

最後,有靜態初始化其是在第一次加載類時所運行的代碼塊(其是通常剛剛之前的一類被實例化的第一次中的應用程序)和(等靜態方法)不能訪問非靜態字段或方法。

public class SomeObject { 

    private static int x; 

    static { 
     x = 7; 
    } 
} 

道歉,如果這進入比需要更多的細節,我被邀請到這裏從另一個問題,其中的細節是有點更合適的移動這個答案。