2012-08-10 129 views
20

所以我的編碼器朋友討厭使用static編碼。然而我的Java程序充滿了它在類之間的聯繫,而且我有很多它們!Java靜態與實例

是否值得重寫整個代碼來移除靜態方法?

使用一個比另一個有什麼優勢嗎?

+2

我發現使用靜態變量保持狀態使得程序不可維護,這基本上就像使用全局變量。由於沒有任何代碼可以從任何地方訪問代碼,即類別代碼,因此類中的私有靜態代碼不會有同樣的問題。 – 2012-08-10 18:25:48

回答

33

1.一個實例變量是每個對象一個,每一個對象具有實例變量的其自己的副本。

如:

public class Test{ 

    int x = 5; 

} 

Test t1 = new Test(); 
Test t2 = new Test(); 

兩個t1t2有它自己的x副本。

2.靜態變量是類共享相同的靜態變量的每一個對象每一個,

如:

public class Test{ 

    public static int x = 5; 

} 

Test t1 = new Test(); 
Test t2 = new Test(); 

兩個t1t2將有只有一個X在它們之間共享。

3.當JVM加載類時,會初始化一個靜態變量。

4.static method不能訪問Non-static變量或方法。

5.Static methodsStatic variables可以模仿一個Singleton Pattern一起,但這不是正確的方式,如當有很多類,那麼我們不能肯定的類加載順序JVM,這可能會造成問題。

+4

我不認爲問題是什麼是靜態變量以及它們爲什麼不好。這是否值得去除他的編碼器朋友說的不好的靜態變量。 – 2012-08-10 18:57:25

+4

我已經描述了它們是什麼以及它們如何與類相關聯。現在它由編碼員朋友決定是否使用或不使用......我在第五點中也提到它有時會變得糟糕 – 2012-08-11 09:14:44

7

static是,你不希望有一份爲每個實例

instance變量是您要爲對象的每個實例單獨副本案件的情況。

根據業務案例,使用哪一個可能會改變。

+0

問題是靜態字段通常是代碼嗅覺的一個實例。特別是OP提到的,因爲它們用於類之間的通信,所以它們基本上是全局變量。我遠離任何不是隻讀的公共靜態變量。 – 2012-08-10 18:23:49

+0

@JuanMendes:同意你的評論。 – kosa 2012-08-10 18:29:46

+0

這和將它用於函數和變量一樣嗎? – Kezz101 2012-08-10 19:39:21

3

垃圾收集 - 靜態字段的壽命比實例字段長得多。 從邏輯的角度來看,靜態字段是ONLy假設在每個實例之間共享的 - 如果它確實是你的情況,那麼當然沒有問題。

+1

我認爲你的觀點是公共靜態變量是壞的(除了常量) – 2012-08-10 18:53:30

+0

@JuanMendes所以真實!應該提到這一點。謝謝 – Eugene 2012-08-10 18:54:57

4

如果你有太多的靜態函數和變量,它可能會導致更多的功能,而不是真正的OO。此外,如果你有公共靜態變量,那麼你複製不好的全局變量。跟蹤它們是一場噩夢。

通常我的原則是,如果你能使用實例變量,只有具有靜態變量和函數,如果真的是在一個類,而不是一個對象一般

這是一個相當好的回答一個類似的問題 Java: when to use static methods

不僅僅是鏈接到方法,而是考慮使用新操作來創建一個新對象並以非靜態方式從中訪問該方法。

public void myMethod(){ 
    Time.setTime(Time.getTime() + 20); 
    System.out.println(Time.getTime()); 
} 

public void myMethod(){ 
    Time t = new Time(); 
    t.setTime(t.getTime() + 20); 
    System.out.println(t.getTime()); 
} 

是在這些方法中舉行現在是向您創建時間實例的任何狀態。如果需要,您也可以在其他方法中共享變量t。

+0

那麼公共靜態變量究竟有什麼不好呢? – Kezz101 2012-08-11 14:14:18

+0

麻煩的是,他們模仿全局變量。這些代碼可以在代碼中的任何地方更新,這使得很難跟蹤哪裏更新以及它們處於什麼狀態。它可能會導致很難找到的錯誤。這個鏈接很好解釋它。 http://c2.com/cgi/wiki?GlobalVariablesAreBad如果你想更清晰的讓我知道 – RNJ 2012-08-12 21:26:29

+0

啊,我現在明白了!感謝您的確認:D – Kezz101 2012-08-13 15:03:01

0

當你使用靜態對象(除了單例情況),你實際上正在實現與全局變量相結合的函數式編程。如果你這麼做 - 你應該重新考慮你的設計或使用Java(也許你應該使用功能性編程語言,如列表,方案等)。

1

你說的是靜態方法還是靜態屬性?

就靜態方法而言,只有一種方法可以濫用它們,那就是當您定義將對象實例作爲參數的方法時。你不應該這樣做,我認爲這樣做是不好的編碼習慣。這裏有一個例子:

static int add(ThisClass a, ThisClass b) { 
    return a.value + b.value; 
} 

如果你在談論在類的靜態變量,你基本上到這是那裏的目的是隻有一個特定類的實例「單身」的主題。單身人士受到很多虐待。它們被許多類庫(認爲JDNI和日誌記錄類)使用,但是如果應用程序廣泛使用它們,它可能是一個結構不良的程序的標誌。這可能是你的朋友所憎恨的。

0

臨靜態

一旦靜態構件從內部或類的外部,那麼類的靜態構造函數被調用調用。 「靜態對象」將貫穿整個會話,因此您將贏得表現。

精讀靜態

靜態成員不能有狀態,因此他們不能談論到類的非靜態成員。

如果我們考慮BigInteger class,這個類如果某些部分被做成靜態成員將獲得

該類的一個實例表示(如預期的)一個大整數。

但是,主要的方法增加和乘法不是靜態的(它們應該處於更好的世界),這對性能不利。

因此,在實踐中,人們不應該害怕靜態和非靜態之間的混合。

0

我不喜歡使用靜態變量或方法,因爲它們沒有真正的繼承。這使得嘲笑測試變得更加困難。使用實例爲您提供了完全多態的靈活性。另一方面,有時需要靜態變量,例如全局緩存。如果靜態方法爲您無法訪問或擴展的類/對象/基元提供輔助方法,那麼這些方法可能會有所幫助。這些輔助方法非常簡單,不需要繼承。例如java.util.Arrays類或java.util.Collections。

1

實例和靜態變量:

回答你的問題:我會說這是值得使用靜態變量來節省內存分配。

內存分配:

對於靜態變量僅一個存儲位置被分配irespective沒有創建的對象和用於實例變量每個對象一個存儲器位置分配

現在考慮該例子中,考慮你正在從事公司內部項目,你必須創建1M對象到員工類和某些屬性到員工類是e id,ename,ecompany現在重要的事情是,所有員工都在XYZ公司如此重視財產ecompany將是「XYZ」,不論員工。

現在你知道的情況下,價值的財產企業網站管理系統是要去XYZ 100萬級的對象。

現在,您決定要聲明ecomapny財產作爲靜態或實例考慮內存分配

,如果你把它聲明爲分配給企業網站管理系統靜態然後最小內存將只有48字節,這非常少的比較到需要存儲1百萬個實例變量的內存。 100000 * 48字節= 48百萬字節。