Java:静态类?

Nic*_*ner 128 java oop static class utility

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

Dav*_*les 160

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

  • @matt b:正如David Robles在他的回答中指出的那样,你不需要让类最终......它不能被子类化,因为子类将无法调用超类构造函数,因为它是私有的.但是......没有明确的伤害.但是jfyi :-). (18认同)

Dav*_*les 93

根据伟大的书"Effective Java":

第4项:使用私有构造函数强制实现非实例化

- 尝试通过使类抽象来强制执行非实例化不起作用.

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

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

因为显式构造函数是私有的,所以它在类之外是不可访问的.AssertionError不是严​​格要求的,但是如果在类中意外调用构造函数,它会提供保险.它保证在任何情况下都不会实例化该类.这个成语有点违反直觉,因为构造函数是明确提供的,因此无法调用它.因此,如上所示,包括评论是明智的.

作为副作用,这个习惯用法也可以防止类被子类化.所有构造函数必须显式或隐式地调用超类构造函数,并且子类将不具有可调用的可访问超类构造函数.


cro*_*wne 21

听起来你有一个类似于java.lang.Math的实用程序类.
这种方法有最终类,包含私有构造函数和静态方法.

但要注意这对可测试性的作用,我建议阅读本文
静态方法是可测性的死亡

  • 那么 java.lang.Math 是“可测试性的死亡”吗? (2认同)

Ben*_*ill 6

只是为了向上游游泳,静态成员和班级不参与OO,因此是邪恶的.不,不是邪恶,但严重的是,我会推荐一个带有单身模式的常规课程.这样,如果您需要在任何情况下覆盖行为,这不是一个重大的重组.OO是你的朋友:-)

我的$ .02

  • 单身人士也被认为是邪恶的. (17认同)
  • OO有它的位置,但有时候它不实用,或者它会浪费资源 - 例如,像Math.abs()这样简单的东西.没有理由仅仅为了实例化一个对象来实例化一个对象,当静态方法调用也可以为你提供服务而没有任何OO开销.;) (12认同)
  • 单身并不比依赖注射更邪恶:) (5认同)
  • 您使用私有构造函数来阻止任何人实例化或子类化该类.请参阅David Robles的回答:http://stackoverflow.com/questions/1844355/java-static-class/1844388#1844388 (3认同)
  • @rob re OO,我同意,Math.Abs​​可能永远不需要一个实例.当我听到"我有一个实用工具类"时,我会看到Math.Avg(),你现在需要添加支持加权平均值.我看到一个Url生成器,param in,url out需要重构以支持href,或仅限url等等.由于这些原因,拥有基于OO的实用程序类可以回报.此外,现在我将放弃标准的OO防御战术,测试!/我鸭子 (2认同)