Java:静态类?


130

我有一个充满实用程序功能的类。实例化它的实例没有语义,但是我仍然想调用它的方法。处理此问题的最佳方法是什么?静态课?抽象?


14
顺便说一句,您不能使顶级课程静态……
乔恩(Jon)2009年

Answers:


163

标记为final的类上的私有构造函数和静态方法。


19
@matt b:正如David Robles在他的答案中指出的那样,您不需要使类最终化……它不能被子类化,因为子类因为是私有的而无法调用超类构造函数。但是...露骨无害。但是jfyi :-)。
汤姆”,

93

根据伟大的著作《有效的Java》

第4项:使用私有构造函数强制执行不稳定性

-试图通过使类抽象化来强制不可例行性是行不通的。

-仅当类不包含显式构造函数时,才会生成默认构造函数,因此可以通过包含私有构造函数使该类不可实例化:

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

由于显式构造函数是私有的,因此在类外部无法访问。并非严格要求AssertionError,但可以提供保证,以防在类中意外调用构造函数。它保证了在任何情况下都不会实例化该类。这个惯用法有点违反直觉,因为明确提供了构造函数,因此无法调用它。因此,明智的做法是添加一条评论,如上所述。

副作用是,此惯用法还防止类被子类化。所有构造函数都必须显式或隐式调用超类构造函数,并且子类将没有可调用的可访问超类构造函数。


1
你为什么选择AssertionError了像其他的替代品IllegalStateExceptionUnsupportedOperationException等等?
Pacerier 2014年

@Pacerier看到这个
bcsb1001 2014年

@ bcsb1001,这使我们想到了这一点
Pacerier 2014年


6

只是为了向上游游泳,静态成员和类并不参与OO,因此是邪恶的。不,不是邪恶的,但是认真地说,我建议使用具有单例模式的常规类进行访问。这样,如果您在任何情况下都需要覆盖行为,则不是主要的重组。OO是你的朋友:-)

我的$ .02


17
单身人士也被认为是邪恶的。
丹·代尔

3
您可以使用私有构造函数来防止任何人实例化或子类化该类。参见David Robles的答案:stackoverflow.com/questions/1844355/java-static-class/…–
抢劫

5
单身人士并没有比依赖注入更邪恶:)
无可争议的

12
OO占有一席之地,但有时它只是不切实际,否则会浪费资源,例如,像Math.abs()这样简单的东西。当静态方法调用同样可以为您提供服务而没有任何OO开销时,就没有理由仅仅为了实例化对象而实例化对象。;)
抢劫

2
@rob re OO,我同意,Math.Abs​​可能永远不需要实例。当我听到“我有一个实用程序类”时,我看到Math.Avg(),您现在需要在其中添加加权平均值的支持。我看到一个URL生成器,param in,url out,需要进行重构以支持href或仅url等。由于这些原因,拥有基于OO的实用程序类可以得到回报。另外,现在我将放弃标准的OO防御策略,进行测试!/ me ducks
Bennett Dill

3

评论“私有构造函数”论点:来吧,开发者不是那么愚蠢;但是他们很懒。创建一个对象然后调用静态方法?不会发生。

不要花费太多时间来确保您的课程不会被滥用。对您的同事有一些信心。无论您如何保护课堂,总有一种滥用课堂的方法。唯一不能滥用的是完全没有用的东西。


7
一个看过(在生产代码中,而不是在学生代码中)object.staticMethod的人我认为您高估了Joe Random Programmer的能力!:-P
TofuBeer

2
  • 最终课程和私有构造函数(不错,但不是必需的)
  • 公共静态方法

1

将类声明为毫无意义static。只需声明其方法static,然后像普通的Java Math类一样从类名中调用它们即可。

另外,即使严格没有必要将构造函数设为私有,这样做也是一个好主意。将构造函数标记为私有可防止其他人创建您的类的实例,然后从这些实例中调用静态方法。(这些调用在Java中的工作原理完全相同,只是误导并损害了代码的可读性。)


1
另外,不要忘记创建私有构造函数。
Asaph

@Asaph:同意。我在回答上加了一点。谢谢。
比尔蜥蜴

如果要在内部类中使用静态方法,则该类也必须是静态的。
Rui Marques 2013年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.