您對內存泄漏問題
我想說這裏會有沒有內存泄漏問題開始。實際上,這兩種情況下的內存泄漏完全相反(在這方面它們是相同的)。 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
'靜態'方法很少用於這些嘗試('get'或'set')。 – Andrew
您正在隱藏實現細節(如所有封裝)。這使您可以修改它而不會破壞代碼。如果你想以「Data」類型存儲數據,你可以改變字段變量,然後在'setString'方法(我建議改變名字)和'Data'中將'String'解析爲'Data' ''getString'方法中的'String'。 –
你可能想要閱讀這個鏈接,主要討論需要首先獲取/設置方法! http://stackoverflow.com/questions/1568091/why-use-getters-and-setters?lq=1 – AADProgramming