2009-12-04 87 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