2012-02-11 55 views
0

在我問這個問題之前,我想提供一些清晰的代碼。以下是我的單身課程代碼。需要關於java中單例類的信息

public class CoreData { 

    private boolean VarA; 

    private static CoreData instance = null; 

    protected CoreData() { 
      // Exists only to defeat instantiation. 
    } 

    public static CoreData getInstance() { 
      if(instance == null) { 
      instance = new CoreData(); 
      } 
      return instance; 
    } 

    public boolean getVarA(){ 
     return VarA; 
    } 

    public void setFirstTime(boolean B){ 
     VarA = B; 
    } 
} 

現在我有幾個問題要問

  1. 會有什麼區別,如果讓成員變量翻靜態?
  2. 我可以在方法getInstance()中初始化成員變量嗎?
  3. 初始化Singleton類中成員變量的最佳做法是什麼?
  4. 使這個類成爲最終的含義是什麼?
  5. 使成員變量最終的含義是什麼?

我對java和OOPS很新。我現在正在學習它。如果有人回答我的問題以使我的知識更好,我將不勝感激。

+1

受保護的構造函數並不能擊敗instantation(來自外部),private可以。 – 2012-02-11 11:46:20

回答

0

如果將成員變量VarA設置爲static,會有什麼區別?

將變得更加困難,使其成爲非單身後來

我可以初始化的方法getInstance()成員變量?

是的。爲什麼不。但實際上構造函數是爲此而完成的。

初始化Singleton類中成員變量的最佳做法是什麼?

通過最佳實踐,您應該使用一些IoC,並且不要在邏輯代碼中放置任何有關作用域的代碼。

使這個類成爲最終的含義是什麼?

,您應該使用private構造函數,而不是一個protected或使final防止通過擴展創建多個實例。像new CoreData(){};

使成員變量最終是什麼意思?

我相信所有的變量應該是最終的默認。它也可以幫助你解決多線程問題。

+0

感謝您的回答。你可以請一些燈光,我怎麼能初始化getInstance()方法中的變量。如果我直接賦值給成員,它告訴我一個「不能靜態引用非靜態字段」 – 2012-02-11 11:55:31

+0

@Surjya Narayana Padhi就像'if(instance == null){instance = new CoreData() ; instance.VarA = false;}' – 2012-02-11 12:05:09

+0

如果所有的變量默認都是最終的,他們應該被稱爲不同的東西。哦,等等,我知道......讓我們稱他們爲常量! – Perception 2012-02-11 13:10:18

2

因爲你只有一個實例(或者你認爲 - 見下文)使它靜態應該沒有任何區別。

你的代碼不是線程安全的!你可以創建兩個實例。原因是,在檢查實例爲空之後,另一個線程也可以檢查並找到它 - 這兩個線程都會創建實例並返回它們。人會「逃跑」。

傳統的辦法是「雙重檢查鎖定」,其中檢查, synchronized塊,但像比爾·皮尤在他famous article指出的那樣,這是一個破碎的模式。 Java 1.5引入了volatile關鍵字來解決這個問題,但它仍然是難看的代碼。

現代的最佳實踐方法懶惰初始化實例,就是用這些模式之一:

public class CoreData { 

    private static class InstanceHolder { 
     static CoreData INSTANCE = new CoreData(); 
    } 

    public static CoreData getInstance() { 
     return InstanceHolder.INSTANCE; 
    } 
} 

public static enum CoreData { 

    INSTANCE; 

    // rest of class 
} 

兩者都是由語言保證創建單身,但枚舉版本是「鐵皮」 - 它有可能通過反序列化破解影響該實例的狀態在靜態持有者類模式中。除了這個微小的漏洞,兩者都有效。我更喜歡我的代碼中的第一個選項,因爲它可以避免類膨脹。

+0

感謝您的好建議,使其線程安全。這是一個爲我學習的新東西。你可以請一些燈光,我怎麼能初始化getInstance()方法中的變量。如果我直接將值賦給成員,它告訴我一個「無法對非靜態字段進行靜態引用」。 – 2012-02-11 11:43:35

+0

@波希米亞,感謝這個不錯的信息和關於雙重檢查鎖定的文章。 – 2012-02-11 12:15:09

+0

很好的總結。 +1。 – Perception 2012-02-11 13:13:03

相關問題