2015-08-08 22 views
3

我搜索了最佳方式來保存/共享要在全局和預期使用的數據,我發現了很多答案。引起我注意的一個方法是使用靜態字段。然而,靜態字段的方式表示有這樣的:使用靜態字段,使用Getter和Setter和靜態字段之間的差異公開

public class DataHolder 
{ 
    private static String dataString; 

    public static String getDataString 
    { 
     return dataString; 
    } 

    public static void setString(String dataString) 
    { 
     this.dataString = dataString; 
    } 
} 

但我總是做這種方式:

public class DataHolder 
{ 
    public static String dataString; 
} 

我只是想知道是不是後者比第一更容易?因爲我不必設置任何getter和setter方法。我沒有看到兩者之間的區別。那麼爲什麼不推薦第二個?

我之前也被告知,做我的方式有時會導致內存泄漏問題。但是第一個解決方案不會導致內存泄漏問題嗎?

+0

'靜態'方法很少用於這些嘗試('get'或'set')。 – Andrew

+1

您正在隱藏實現細節(如所有封裝)。這使您可以修改它而不會破壞代碼。如果你想以「Data」類型存儲數據,你可以改變字段變量,然後在'setString'方法(我建議改變名字)和'Data'中將'String'解析爲'Data' ''getString'方法中的'String'。 –

+1

你可能想要閱讀這個鏈接,主要討論需要首先獲取/設置方法! http://stackoverflow.com/questions/1568091/why-use-getters-and-setters?lq=1 – AADProgramming

回答

2

您對內存泄漏問題

我想說這裏會有沒有內存泄漏問題開始。實際上,這兩種情況下的內存泄漏完全相反(在這方面它們是相同的)。 DataHolder類只能有一個String實例(因爲它是靜態的,它不屬於任何DataHolder實例)。

想象一下,這是不是靜態的:

public class DataHolder 
{ 
    String dataString; 
} 

這意味着,每一次這樣做new DataHolder(),你將有一個字符串的一個單獨的實例。用你的靜態dataString,只會有一個實例。

getter和setter和同步

之所以你的實現是壞的,因爲它不是線程安全的,因爲米塔爾的Piyush指出。儘管他沒有涉及任何細節,所以我想補充兩分錢。

你不能說這僅僅是因爲你只希望它在一個線程中使用,它只會在一個線程中使用。 Swing線程就是一個很好的例子,其中只有一個線程處理UI。在這種情況下,你會期望只有一個線程存在,並且可以這樣做。但是,任何後臺工作都必須在SwingWorker線程中完成,因此在此創建一個SwingWorker線程來提供數據競爭機會,因爲現在有兩個線程。出於這個原因,你應該總是有靜態變量的getter和setter。

這就是說,您提供的代碼片段與您的兩個示例(由於沒有同步生成新堆棧幀的小差異)完全相同。你想這樣做:

public class DataHolder{ 
    private static String dataString; 
    public static String getDataString(){ 
    synchronized(DataHolder.class){ 
     return DataHolder.dataString; 
    } 
    } 

    public static void setString(String dataString){ 
    synchronized(DataHolder.class){ 
     DataHolder.dataString = dataString; 
    } 
    } 
} 

我確實改變了一些關於你的代碼的東西。第一個也是最明顯的是沒有這個關鍵字用於靜態變量。正如我之前暗示的那樣,因爲它的靜態不屬於任何實例。 「這個」在靜態環境中不是一件事情。

我做的另一件事是放在方法的同步內部。我這樣做有兩個原因。首先是偏好;有些人更喜歡保持同步的功能簽名,所以它從調用者混淆,所以他們不做假設,因爲該功能是同步的。這是首選。我做這件事的另一個原因是因爲我想明顯地表明,當你在簽名中同步一個函數時,它實際上將看起來是「底層的」。如前所述,由於沒有「this」,它實際上將在類本身上進行同步。

我想你大概可以使用一些關於static關鍵字的閱讀。我認爲你的困惑來自於你不瞭解它的事實,並且在理解靜態本身之前,你試圖回答關於靜態變量的getter和setter的問題。這裏有一個鏈接,我找到一個快速的谷歌搜索,可能讓你開始: http://www.javatpoint.com/static-keyword-in-java

1

不知道內存泄漏。

但是:多個並行的請求 - 多線程,你一定在這裏有一個線程問題 - 這不是線程安全除非你照顧(例如使用同步)。

1

我更喜歡getter/setters,而不是公共領域。

這種封裝允許您修改屬性的類型而不會破壞那些使用它的人的代碼。

如果您決定創建一個Data類型,而不是將其存儲爲String,該怎麼辦? (爲了增加類型安全性)。

有了公共領域,這是不可能的。但是,使用getter/setter方法,您可以執行允許這種需要解析:

class SomeClass { 
    private static Data data; 

    public static void setData(String data) { 
     data = new Data(data); 
    } 

    public static String getData() { 
     return data.toString(); 
    } 
} 

class Data { 
    private String data; 

    public Data(String data) { 
     this.data = data; 
    } 

    public String toString() { 
     return data; 
    } 
} 

這不是一個內存泄漏問題,因爲它沒有任何關係分配內存。使用該數據時,線程之間可能會有一些不一致,因爲它不是線程安全的,但任何泄漏都不是使用靜態的結果,而不是多線程正確。

而不是全局訪問某些東西,您應該將依賴關係傳遞到需要的地方。例如,使用全局變量的方法。通過參數將值傳遞給它。這被稱爲依賴注入。