![](/img/trans.png)
[英]Difference between non- final public static and non- final public instance fields in terms of security?
[英]Difference Between Using Static Fields That Uses Getter And Setter And Static Fields That Are Declared Public
我搜索了保存/共享全局使用數據的最佳方法,並且按照預期我找到了很多答案。 引起我注意的方法之一是使用靜態字段。 但是,那里說的靜態場方式是這樣的:
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方法。 我認為這兩者之間沒有任何區別。 那么為什么不推薦第二個呢?
我之前也被告知,按照我的方式行事會導致內存泄漏問題。 但第一個解決方案不會導致內存泄漏問題嗎?
對內存泄漏不太了解。
但是:多個並行請求 - 多個線程,你肯定有一個線程問題 - 這不是線程安全的,除非你照顧(例如使用synchronized )。
我更喜歡getter / setter,而不是公共領域。
這種封裝允許您修改屬性類型, 而不會破壞使用它的代碼。
如果您決定創建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;
}
}
這不是內存泄漏問題,因為它與分配內存無關。 在使用該數據時,線程之間可能存在一些不一致,因為它不是線程安全的,但任何泄漏都不是使用靜態而不是正確多線程的結果。
您應該將依賴項傳遞到所需的位置,而不是全局訪問。 例如,使用全局變量的方法。 通過參數將值傳遞給它。 這稱為依賴注入。
關於內存泄漏的問題
我想先說這里沒有內存泄漏問題。 事實上,在兩種情況下,它都與內存泄漏完全相反(在這方面它們是相同的)。 對於DataHolder類,您只能有一個String實例(因為它是靜態的,它不屬於任何DataHolder實例)。
想象一下它不是靜態的:
public class DataHolder
{
String dataString;
}
這意味着每次執行new DataHolder()
,都會有一個單獨的String實例。 使用靜態dataString,只會有一個實例。
Getter和Setter以及同步
Piyush Mittal指出,你的實現不好是因為它不是線程安全的。 他沒有詳細說明,所以我想加兩分錢。
你不能說這只是因為你只希望它在單個線程中使用,它只會在一個線程中使用。 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.