2009-12-04 85 views
123

我有一個充滿實用功能的課程。實例化它的一個實例沒有語義意義,但我仍然想調用它的方法。處理這個問題的最佳方法是什麼?靜態類?抽象?Java:靜態類?

+14

你不能讓一個頂級類的靜態的方式... – Jon 2009-12-04 01:51:32

+0

請,不這樣做!這是爲什麼:http://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html – yegor256 2016-06-28 02:40:33

回答

153

標記爲final的類上的私有構造函數和靜態方法。

+17

@matt b:正如David Robles在他的回答中指出的那樣,您不需要使類最終...它不能被子類化,因爲子類將不能調用超類構造函數,因爲它是私有的。然而......沒有明顯的傷害。但jfyi :-)。 – Tom 2009-12-04 07:07:01

+1

@David,你爲什麼發佈兩個答案? http://stackoverflow.com/a/1844388/632951 – Pacerier 2014-06-25 00:37:35

1

宣佈課程爲static毫無意義。只需聲明它的方法static並像普通類一樣從類名中調用它們,如Java的Math類。

此外,即使並非嚴格需要將構造函數設爲私有,但最好這樣做。將構造函數標記爲私有可以防止其他人創建您的類的實例,然後從這些實例中調用靜態方法。 (這些調用工作完全在Java中一樣,他們只是誤導和傷害你的代碼的可讀性。)

+1

另外,不要忘記做一個私人的構造函數。 – Asaph 2009-12-04 01:47:11

+0

@Asaph:同意。我在回答中添加了一些內容。謝謝。 – 2009-12-04 02:04:45

+0

如果你想在內部類中使用靜態方法,那麼這個類也必須是靜態的。 – 2013-03-28 16:03:04

90

按照偉大的書"Effective Java"

項目4:強制noninstantiability與私有構造

- 嘗試通過使類抽象不起作用來強制實現不可信性。

- 生成一個默認的構造函數只有當一個類中沒有顯式的構造,因此一個類可以製成noninstantiable通過包括私有構造:

// Noninstantiable utility class 
public class UtilityClass 
{ 
    // Suppress default constructor for noninstantiability 
    private UtilityClass() { 
     throw new AssertionError(); 
    } 
} 

因爲明確的構造函數是私有的,它在班級之外是無法進入的。 AssertionError不是嚴​​格要求的,但它提供了保險,以防構造函數在類中被意外調用。它保證在任何情況下類永遠不會被實例化。這個習慣用法是輕度違反直覺的,因爲構造函數是明確提供的,所以它不能被調用。因此,如上所示,包括評論是明智的。

作爲一個副作用,這個習語還可以防止類被分類。所有構造函數都必須顯式或隱式調用超類構造函數,並且子類不能調用可訪問的超類構造函數。

+1

爲什麼你選擇'AssertionError'比其他選擇像'IllegalStateException','UnsupportedOperationException'等? – Pacerier 2014-06-25 00:36:49

+0

@Pacerier看到[這個](http://stackoverflow.com/questions/398953/what-is-the-preferred-throwable-to-use-in-a-private-utility-class-constructor)。 – bcsb1001 2014-10-31 14:11:32

+0

@ bcsb1001,這將我們帶到[this](http://stackoverflow.com/questions/398953/what-is-the-preferred-throwable-to-use-in-a-private-utility-class-constructor/ 399074#comment41967347_399074)。 – Pacerier 2014-10-31 23:00:31

6

只是遊向上遊,靜態成員和班級不參與面向對象,因此是邪惡的。不,不是邪惡的,但嚴重的是,我會推薦一個帶有單身模式的普通課程。這樣,如果你需要在任何情況下覆蓋行爲,這不是一個重大的改變。 OO是你的朋友對「私有構造」參數:-)

我的$ .02

+17

單身人士也被認爲是邪惡的。 – 2009-12-04 02:08:03

+0

你是對的,我不知道哪個更糟。最終,我喜歡練習最有意義的解決方案,完全有可能需要靜態類。問題是,如果所有的方法都是靜態的,爲什麼還要有私人的ctor?對我來說,私人ctor與單身模式一起使用。如果'他們'想要一個沒有成員的類的實例,讓他們擁有它;-) – 2009-12-04 02:11:51

+3

您使用私有構造函數來阻止任何人實例化或繼承這個類。見大衛羅伯斯的答案:http://stackoverflow.com/questions/1844355/java-static-class/1844388#1844388 – rob 2009-12-04 02:30:37

2

評論:來吧,開發商也沒有那麼蠢;但他們很懶。創建一個對象然後調用靜態方法?不會發生。

不要花太多時間來確保您的班級不會被濫用。對你的同事有一些信心。無論你如何保護它,總會有一種方法濫用你的課程。唯一不能被濫用的東西是完全無用的。

+7

一個曾經看過(在生產代碼中,不是jsut學生代碼)的人object.staticMethod我認爲你高估了Joe Random Programmer的能力! :-P – TofuBeer 2009-12-04 02:49:14

2
  • 最終集體和私人的構造函數(好的,但不是必要的)
  • 公共靜態方法
20

聽起來像是你有類似java.lang.Math一個工具類。
該方法有私有構造函數和靜態方法的最終類。

但要注意的是什麼這樣做可測試性,我建議你閱讀這篇文章
Static Methods are Death to Testability

+0

那麼java.lang.Math是「死於可測試性」嗎? – Pacerier 2014-06-25 00:21:52

+1

通過https://code.google.com/p/testability-explorer/查看它的得分可能會很有趣。 – crowne 2014-06-25 20:22:35