假设我有一个被设计为实例化的类。我在类中有几个私有的“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作为静态方法-或者有特别的理由不这样做?

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


当前回答

使用静态方法的一个问题是,它会使对象在单元测试中更难使用。Mockito不能为静态方法创建模拟,也不能创建该方法的子类实现。

其他回答

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

Yes.

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

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

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

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

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

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

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

我更喜欢这样的帮助方法是私有静态的;这将使读者清楚,他们不会修改对象的状态。我的IDE还将以斜体显示对静态方法的调用,因此我无需查看签名就知道该方法是静态的。

跑题:我会把辅助方法放在一个独立的实用程序/辅助类中,其中只有静态方法。

在使用点(阅读为“相同的类”)拥有帮助方法的麻烦在于,某些人可能会选择将他们自己不相关的帮助方法发布在相同的位置

使用静态方法的一个问题是,它会使对象在单元测试中更难使用。Mockito不能为静态方法创建模拟,也不能创建该方法的子类实现。

正确答案是:

任何不从字段中获取任何信息,也不向字段中放入任何信息的方法都不必是实例方法。任何不使用或改变其类或对象中的任何字段的方法都可能是静态方法。