【问题标题】:When should a method be static?什么时候方法应该是静态的?
【发布时间】:2008-09-07 20:28:46
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: language-agnostic static


    【解决方案1】:

    当方法不是实例的一部分时,将它们设为静态。不要担心微优化。

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

        • 感谢您的回答。我经常将一些方法设为静态(因为它们实际上并不是实例的直接部分)。但是现在我避免将这些方法设为静态,因为你是对的,模拟是不可能的
        【解决方案4】:

        请记住,每当您编写静态方法时,您就是在编写一个无法轻易修改其行为的不灵活方法。

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

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

        【讨论】:

          【解决方案5】:

          @jagmal 我认为您在某处有一些交叉 - 您列出的所有示例显然都不是静态方法。

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

          对于汽车示例,速度、行驶公里数显然与属性相关。在汽车级别考虑时,换档和速度计算是依赖于属性的 - 但考虑从汽车继承的 carModel 类:此时它们可以成为静态方法,因为所需的属性(例如车轮直径)可以定义为该级别的常量。

          【讨论】:

          • 你是对的。我真的把事情搞砸了。可能是因为那几天我睡眠不足。本着 SO 的精神,我删除了评论,我认为除了人们已经告诉的内容之外,我没有什么要补充的了。无论如何,谢谢。
          【解决方案6】:

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

          但是,它很可能正处于噪音之中 - 特别是对于允许优化不必要的参数传递的语言。

          【讨论】:

          • 在重要的时候(大部分时间)完全由编译器优化掉。
          • 它不能在 C++ 中被优化掉。调用者无法知道被调用者不会使用“this”,因此无论如何都必须传递它。对于其他语言,YMMV。
          【解决方案7】:

          这里有一个关于 why String.Format is static 的相关讨论,其中将突出一些原因。

          【讨论】:

            【解决方案8】:

            将方法设为静态时要考虑的另一件事是,任何能够看到该类的人都能够调用静态方法。而当方法是实例方法时,只有有权访问实例的人才能调用该方法。

            【讨论】:

              猜你喜欢
              • 2012-09-15
              • 2010-09-17
              • 2016-02-15
              • 2011-03-23
              • 1970-01-01
              • 2011-01-06
              • 2011-10-14
              • 1970-01-01
              • 2014-05-28
              相关资源
              最近更新 更多