假设我有一个被设计为实例化的类。我在类中有几个私有的“helper”方法,它们不需要访问任何类成员,只对它们的参数进行操作,并返回一个结果。

public class Example {
   private Something member;

   public double compute() {
       double total = 0;
       total += computeOne(member);
       total += computeMore(member);
       return total;         
   }

   private double computeOne(Something arg) { ... }
   private double computeMore(Something arg) {... } 
} 

是否有特别的理由指定computeOne和computeMore作为静态方法-或者有特别的理由不这样做?

当然,让它们保持非静态状态是最简单的,尽管它们当然可以是静态的,而不会引起任何问题。


当前回答

就像很多人说的那样,让它成为静态! 以下是我遵循的经验法则:如果你认为方法只是一个数学函数,即它是无状态的,不涉及任何实例变量(=> no blue color vars [in eclipse]在方法中),方法的结果将是相同的'n'次调用(当然,具有相同的参数),然后将该方法标记为STATIC。

如果你认为这个方法对其他类有用,那么把它移动到Util类中,否则,把这个方法作为私有的放在同一个类中。(尽量减少可达性)

其他回答

如果该方法基本上只是一个子例程,永远不会使用状态信息,则将其声明为静态。

这允许它在其他静态方法或类初始化中使用,即:

public class Example {
   //...

   //Only possible if computeOne is static
   public final static double COMPUTED_ONE = computeOne(new Something("1"));

   //...
}

或者有什么特别的理由不(将它们声明为静态的)?

Yes.

通过将它们保留为实例方法,您可以在以后提供不同的实现。

这听起来可能很愚蠢(实际上如果这些方法只由您在50行程序中使用,则会很愚蠢),但在较大的应用程序中,或在其他人使用的库中,您可能会决定选择更好的实现,但又不想破坏现有代码。

因此,在新版本中创建一个子类并返回该子类,由于方法被声明为实例方法,因此只需让多态性完成它的工作。

此外,出于同样的原因,将构造函数设置为私有并提供静态工厂方法也会带来好处。

因此,我的建议是保留它们作为实例方法,并尽可能避免静态方法。 充分利用语言提供的动态特性。

请参见这里的相关视频:如何设计一个好的API以及为什么它很重要

虽然它与“静态vs实例”方法的讨论没有直接关系,但它涉及到API设计中一些有趣的点。

我实在想不出私有静态方法有什么明显的优势。话虽如此,使它们是非静态的也没有什么特别的好处。这主要是一个表示的问题:你可能想让它们是静态的,以清楚地强调它们没有改变对象的事实。

对于具有不同访问权限的方法,我认为有两个主要参数:

可以在不创建对象实例的情况下调用静态方法,这很有用 静态方法不能被继承,如果您需要多态性,这可能是一个问题(但与私有方法无关)。

除此之外,差异非常小,我强烈怀疑传递给实例方法的额外this指针会产生显著差异。

在这种情况下,我倾向于让computeOne和computeMore成为静态方法。原因是:封装。访问类实现的代码越少越好。

在您给出的示例中,您指出computeone和computeMore不应该访问类的内部,那么为什么要给类的维护者干涉内部的机会呢?

如果没有静态修饰符,你就不可能知道这个方法是无状态的,除非你在(重新)编写方法时进行额外的分析。 那么“静态”修饰符可能会给你一些关于重构的想法,而不是其他人认为无用的东西。 例如,将方法移动到某个Utility类或将其转换为成员方法。