公用事业类应该是静态的吗?

时间:2011-08-16 07:11:44

标签: java

如果我必须设计一个Utility类(例如ByteUtils或StreamUtils或StringUtils),那么它们的最佳设计选择是什么。

  • 它们应该是静态类(因为我没有任何状态存储)
  • 它们应该是非静态类(如果不使用这些对象,它们将被gc'd)

PS:通过静态类,我的意思是一个带有静态方法的类(而不是内部静态类)

请为此提供有关设计选择的建议?

10 个答案:

答案 0 :(得分:61)

我的实用程序类看起来像这样:

// final, because it's not supposed to be subclassed
public final class FooUtil {

    // private constructor to avoid unnecessary instantiation of the class
    private FooUtil() {
    }

    public static int doSomethingUseful() {
    }

    // ...
}

请注意,尽管这使得实用程序方法易于测试,并且可以从外部轻松访问,但它也使得使用它们的类很难进行单元测试,因为模拟这些实用程序方法并不容易。拥有太多这样的实用程序类可能是缺乏OO设计(程序编程)的标志,并且可以使代码难以测试。

如果您正在使用依赖注入框架(Spring,Guice,无论如何),那么使用非静态方法使实用程序类可实例化,并使其成为可注入的单例可能是个好主意。这样,可以通过模拟实用程序对象来测试使用这些实用程序方法的类。

答案 1 :(得分:41)

如果它是通用实用程序,则静态是IMO更好。你声明你不会有任何州存储,所以我不明白你为什么要把它作为非静态的。声明它是静态的也会节省内存。

答案 2 :(得分:22)

仅仅因为某些东西可能是静态的,并不意味着它应该是静态的。

还有另一个考虑因素:嘲笑。在测试中模拟静态方法比模拟类实例的行为更难。

谈论不必要的堆分配和GC对象过早优化给我。 JVM在优化这类问题方面做得非常好。

答案 3 :(得分:9)

定义Utility类的最简单方法是作为没有实例的枚举

public enum Utility {;
     public static int utilityMethod(int x) { /* ... */ }
}

实用程序类不应该具有任何状态或具有最小状态,因此您不应该担心GC。

您可以将其他有状态类用于特定目的,例如Builder,Factory,您可以根据需要创建对象,并在完成后将其丢弃。

答案 4 :(得分:4)

使用私有构造函数将类设置为非静态是很好的:

  • 如果我们使类静态化,则在部署应用程序时将加载类,如果它是非静态的,则在调用其静态方法之一时将加载该类
  • 创建私有构造函数将避免实例化类

答案 5 :(得分:3)

通常,实用程序类包含静态方法而没有属性,这种方法使得在不实例化类的情况下更容易使用它们的方法。希望这会有所帮助。

答案 6 :(得分:2)

如果你能让它们变得静止,那么一定要这样做!

换句话说,如果他们没有状态,他们应该是静态的。

答案 7 :(得分:2)

好吧,如果你没有要存储的状态,那么GC没有任何内容,所以我会选择静态,这样就可以避免任何不必要的堆分配和GC。

答案 8 :(得分:2)

纯实用程序类通常应该是静态的。当你有一个具有明确定义的输入和输出的类,没有副作用和没有状态时,那么根据定义它应该是一个静态类。

一般情况下,在必要之前不要增加复杂性(在这种情况下依赖注入),并且这样做有好处。

答案 9 :(得分:0)

这里没有人提到静态实用程序方法不可扩展。你无法覆盖它们。你不能利用OOP(特别是多态,这是OOP最强大的功能)。这导致代码重复。

P.S。我发现这篇文章非常有帮助。 http://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html