方法何时应该是静态的?

时间:2008-09-07 20:28:47

标签: language-agnostic static

此外,静态方法对实例方法有什么性能优势吗?

我最近遇到了以下问题:http://www.cafeaulait.org/course/week4/22.html

  

什么时候方法应该是静态的?

     
      
  1. 既不读取也不写入实例字段
  2.   
  3. 独立于对象的状态
  4.   
  5. 接受参数的数学方法,将算法应用于这些方法   参数,并返回一个值
  6.   
  7. 代替构造函数的工厂方法
  8.   

我对Stack Overflow社区的反馈非常感兴趣。

8 个答案:

答案 0 :(得分:22)

当方法不是实例的一部分时,使方法成为静态。不要轻易放弃微观优化。

您可能会发现有许多私有方法可能是静态的,但您总是从实例方法(或彼此)调用。在那种情况下,这并不重要。但是,如果您希望实际能够测试您的代码,并且可能在其他地方使用它,您可能需要考虑在不同的,不可实例化的类中创建这些静态方法。

答案 1 :(得分:19)

方法是否静态更多的是设计考虑而不是效率。静态方法属于一个类,其中非静态方法属于一个对象。如果您有Math类,则可能有一些静态方法来处理加法和减法,因为这些是与Math相关的概念。但是,如果你有一个Car类,你可能会有一些非静态的方法来改变齿轮和转向,因为它们与特定的汽车有关,而不是一般的汽车概念。

答案 2 :(得分:12)

静态方法的另一个问题是为它们编写单元测试是非常痛苦的 - 至少在Java中。你不能以任何方式模拟静态方法。有post on google testing blog about this issue

我的经验法则是只在没有外部依赖关系(如数据库访问,读取文件,电子邮件等)时编写静态方法,以使它们尽可能简单。

答案 3 :(得分:2)

@jagmal我觉得你已经在某处划过了一些电线 - 你列出的所有例子显然都不是静态方法。

静态方法应完全处理类的抽象属性和概念 - 它们绝不应与实例特定属性相关(如果大多数编译器都会大喊大叫)。

对于汽车示例,速度,kms驱动显然属性相关。在汽车级别考虑时,换档和速度计算取决于属性 - 但考虑从汽车继承的carModel类:此时它们可能成为静态方法,因为所需的属性(例如车轮直径)可以定义为那个级别的常数。

答案 4 :(得分:2)

请记住,无论何时编写静态方法,您都在编写一种不灵活的方法,不能轻易地修改它的行为。

你正在编写程序代码,所以如果程序化是有意义的,那就去做吧。如果没有,它可能应该是一个实例方法。

这个想法取自an article by Steve Yegge,我认为这是一个有趣且有用的读物​​。

答案 5 :(得分:1)

性能方面,C ++静态方法可能比非虚拟实例方法稍快,因为不需要将“this”指针传递给方法。反过来,两者都比虚拟方法更快,因为不需要VMT查找。

但是,噪音很可能正好 - 特别是对于那些允许不必要的参数传递进行优化的语言。

答案 6 :(得分:0)

以下是关于why String.Format is static的相关讨论,其中将强调一些原因。

答案 7 :(得分:0)

使方法静态时要考虑的另一件事是,任何能够看到该类的人都能够调用静态方法。虽然mehtod是一个实例方法,但只有那些有权访问实例的人才能调用该方法。