18

我有一个实用程序类,它具有没有实例变量的非静态方法。所以我正在考虑将所有方法转换为static方法。我怀疑会有任何内存或性能影响。但我只是想确认一下。

将这种方法更改为static对程序有任何性能影响吗?

4

7 回答 7

23

最后一件事要补充人们在这里所说的话。

static由于您已保证编译时绑定,因此使用方法的开销略小。静态方法调用将创建字节码指令invokestatic。]

在典型的场景中,实例方法是在运行时绑定的,并且会创建invokevirtualinvokestatic.

但是,这仅在可能进行数百万次迭代的情况下才有意义,我会警告不要这样做驱动你的类设计。从设计的角度做有意义的事情。根据您的描述,static方法可能是要走的路。事实上,这是创建实用程序类的相对标准做法:

public class MyUtilities {
   private MyUtilities() { } // don't let anyone construct it.
   public static String foo(String s) { ... }
}
于 2012-11-08T13:44:22.990 回答
18

编辑:解决性能方面的问题:不必毫无意义地创建实例会更便宜,但差异很可能是完全不相关的。随着时间的推移,专注于清晰的设计可能变得更加重要。

实用方法通常是静态的,如果一个类中的所有方法都是静态的,那么创建该类final并包含一个私有构造函数以防止实例化可能是值得的。从根本上说,对于不代表任何真实“事物”的实用程序类,构造一个实例没有逻辑意义——所以要避免它。

另一方面,这确实降低了灵活性:如果这些实用方法中的任何一个包含您可能希望以多态方式改变的功能(例如,出于测试目的),那么请考虑将它们保留为实例方法 - 并尝试提取一些有意义的类名来表示涉及的“事物”。(例如,FooConverter实例化 a 有意义 - aFooUtil没有。)

于 2012-11-08T12:12:27.890 回答
3

要使方法有资格转换为 ,必须满足两个要求static

  1. 没有访问实例变量(在您的情况下会遇到这种情况);
  2. 永远不需要被覆盖(为此你可能需要仔细考虑)。

但是,当满足这些要求时,实际上建议将方法设为静态,因为它缩小了运行方法的上下文。

最后,请注意这里没有要讨论的性能问题,任何理论上的差异实际上都支持静态方法,因为它们不涉及动态方法解析。但是,实例方法调用在任何相关的 JVM 实现中都非常迅速。

就记忆而言,故事是相同的:理论上的差异有利于静态方法,但如果与单例实用程序类进行比较,则没有实际差异。

于 2012-11-08T12:11:53.877 回答
3

如果实用程序类不是子类,则将不访问实例变量的方法转换为static是一个好主意。您应该浏览代码并将调用转换为静态语法,即

int res = utilityInstance.someMethod(arg1, arg2);

应转换为

int res = UtilityClass.someMethod(arg1, arg2);

为了清楚起见。

不会对性能产生明显的影响:虽然理论上静态调用的成本略低,但在大多数情况下,差异太小以至于不重要。

于 2012-11-08T12:10:49.217 回答
1

没有状态的实用程序类(java.lang.Math例如)通常具有公共静态方法。这样您就不需要创建类的实例来使用它。

于 2012-11-08T12:10:39.153 回答
0

当您要经常使用特定功能时,静态方法是个好主意。

于 2012-11-08T12:12:46.617 回答
-2

不同之处在于您需要一个实例才能使用它们,因此用户必须创建一个实例,该实例将是

于 2012-11-08T12:11:09.653 回答