2009-08-07 80 views
2

您如何看待下面的方法來模擬java中的靜態類? 您可以添加非靜態方法,但無法調用它們。java中的靜態類的模擬

/** 
    * Utility class: this class contains only static methods and behaves as a static class. 
    */ 
// ... prevent instantiation with abstract keyword 
public abstract class Utilities 
    { 
     // ... prevent inheritance with private constructor 
     private Utilities() {} 

     // ... all your static methods here 
     public static Person convert(String foo) {...} 
    } 
+0

所有答案都是近似的。同樣好。 – Gerard 2009-08-07 08:18:10

回答

5

項目4Effective Java(非常...有效的書)說:

// Noninstantiable utility class 
public final class Utility { 

    private Utility() { 
     throw new AssertionError(); 
    } 
} 

因爲明確costructor是私有的:

  • 你不能實例化它
  • 不能擴展它(因爲如果它被聲明爲final)

AssertionError不是必需的,但它提供了另一個小好處:它防止了costructors被意外地從班內調用。

您還可以創建一個特定的註釋,像@BagOfFunction和註釋類:

@BagOfFunctions 
public final class Utility { 

    private Utility() { 
     throw new AssertionError(); 
    } 
} 

基本上你去換一個自文檔註釋的註釋。

+1

您應該將final添加到您的第一個代碼示例 – 2009-08-07 09:05:35

+1

我喜歡這個答案。尤其是因爲異常甚至會阻止使用反射來創建對象。 – dmeister 2009-08-07 10:54:30

+1

你能解釋@BagOfFunctions註解的用法嗎? – pjp 2009-08-07 12:58:30

3

我的FindBugs插件建議使用最終類而不是抽象類。我在我的項目中使用它。這似乎是一個普遍的習慣用語,如果它成爲一個由FindBugs檢查的規則。

2

我會說,如果你已經HABE私有構造函數

私營公用事業(){}

抽象的關鍵字時並不需要。而是讓它最終。

對於任何實際的方法,與您的版本的區別是微不足道的。

8

這是通常的方法。但是,關鍵字摘要不需要關鍵字。使用私有的構造是足夠的,因爲

  • 它阻止(從類外)
  • 它阻止繼承對象的創建

抽象關鍵字提示用戶該類用戶可能在這裏實現了這個類。

+4

即使繼承被阻止,我仍然會包含'final'關鍵字。 – Thorarin 2009-08-07 07:31:34

2

我更喜歡製作這樣的類final,但不是abstract。儘管這只是個人風格的問題。

順便說一下,我想如果你投入一些精力,仍然可以調用它的實例方法。例如。可以嘗試使用objenesis來創建類的實例。

1

我的建議是:防止不正確使用(即實例化)由放置的javadoc

是不是很簡單?我認爲你的隊友能夠閱讀;)

+0

這是Java中的一個標準習慣用法。看到這樣的課程,你甚至不需要閱讀=)你會發現它只是第一眼看到的效用。 – Rorick 2009-08-07 07:29:50

+0

@Megadix:這並不是說他們無法閱讀Javadoc。更多的是他們不讀Javadoc。就像很多將Java問題發佈到SO的人一樣! – 2009-08-07 08:10:18

+1

在編譯時執行非實例性約束具有很大的價值,您應該儘可能多次 – dfa 2009-08-07 13:25:11

2

我必須同意上面那些。使用「最終」而不是「抽象」。請記住,像「最終」和「抽象」這樣的詞彙與您的同行程序員之間的溝通方式,正如他們對機器的指示一樣。抽象意味着後面會有後代類,而最後的決定意味着你不會通過重構節省下來看到這個類的後代(這是你的意圖)。另外,在我見過的大多數標準中,並且始終如一地在我的公司中,認爲最好的做法是使抽象類的某些內容保留爲未使用狀態,保存爲其他類的父類。 「抽象」被視爲「藍圖」或「一般結構」,你永遠不會駕駛一輛「抽象」汽車。另一方面,final類會永久實例化,特別是Factory模式。