实用工具类应该是静态的吗?
如果我必须devise一个Utility类(比如ByteUtils或者StreamUtils或者StringUtils),那么最好的deviseselect是什么。
- 他们应该是静态类(因为我不会有任何状态存储)
- 它们应该是非静态类(如果这些对象没有被使用,它们将被gc'd)
PS:通过静态类,我的意思是一个类与静态方法(而不是内部静态类)
请给这个deviseselect的build议?
如果它是一个通用的工具,静态是IMO更好。 你说你不会有任何状态存储,所以我不明白你为什么要把它变成非静态的。 声明它是静态的也会节省内存。
我的工具类看起来像这样:
// 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() { } // ... }
需要注意的是,虽然这使得效用方法易于testing,并且易于从外部访问,但也使得使用它们的类很难进行unit testing,因为嘲笑这些效用方法并不容易。 有太多这样的实用程序类可能是缺乏OOdevise(程序编程)的标志,并且确实会使代码难以testing。
如果你正在使用一个dependency injection框架(Spring,Guice,不pipe),那么使用非静态方法使实用类实例化,并使其成为可注入的单例可能是一个好主意。 这样,使用这些实用程序方法的类可以通过模拟实用程序对象来testing。
只是因为某些东西可以是静态的,并不意味着它应该是静态的。
还有另一个考虑:嘲笑。 在你的testing中嘲笑静态方法比嘲笑类实例的行为更困难。
谈论不必要的堆分配和GCing的对象过早优化给我。 JVM在优化解决这类问题方面做得相当不错。
定义一个Utility类最简单的方法就是不带实例的枚举
public enum Utility {; public static int utilityMethod(int x) { /* ... */ } }
一个实用程序类不应该有任何状态或最小状态,所以你不应该担心GC。
您可以为Builder,Factory等特定目的创build其他有状态的类,您可以根据需要创build该对象,并在完成后放弃该对象。
使用私有构造函数将类设置为非静态类很好:
- 如果我们使类是静态的,那么当应用程序被部署时,类将被加载,如果它是非静态的,那么当调用其中一个静态方法时,类将被加载
- 创build一个私有构造函数将避免实例化类
通常,实用程序类包含静态方法而不包含任何属性,这种方法使得在不实例化类的情况下使用它们的方法变得更容易。 希望这可以帮助。
纯粹的工具类通常应该是静态的。 当你有一个定义好input和输出的类时,没有副作用和没有状态,那么根据定义它应该是一个静态类。
一般来说,在必要之前不要增加复杂性(在这种情况下是dependency injection),这样做有好处。
如果你能使它们变成静态的,那么一定要这样做!
换句话说,如果他们没有国家,他们应该是静态的。
那么,如果你没有状态存储,那么GC就没有什么了,所以我会用静态的,这样你就可以避免任何不必要的堆分配和GC。
这里没有人提到静态效用方法是不可扩展的。 你不能覆盖它们。 你不能利用OOP(特别是polymorphysm,这是OOP最强大的function)。 这导致代码重复。
PS我发现这篇文章非常有帮助。 http://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html