【发布时间】:2008-09-07 20:28:46
【问题描述】:
另外,静态方法比实例方法有什么性能优势吗?
我最近遇到了以下情况:http://www.cafeaulait.org/course/week4/22.html:
什么时候方法应该是静态的?
- 既不读取也不写入实例字段
- 独立于对象的状态
- 接受参数的数学方法,将算法应用于那些 参数,并返回一个值
- 代替构造函数的工厂方法
我会对 Stack Overflow 社区对此的反馈非常感兴趣。
【问题讨论】:
另外,静态方法比实例方法有什么性能优势吗?
我最近遇到了以下情况:http://www.cafeaulait.org/course/week4/22.html:
什么时候方法应该是静态的?
- 既不读取也不写入实例字段
- 独立于对象的状态
- 接受参数的数学方法,将算法应用于那些 参数,并返回一个值
- 代替构造函数的工厂方法
我会对 Stack Overflow 社区对此的反馈非常感兴趣。
【问题讨论】:
当方法不是实例的一部分时,将它们设为静态。不要担心微优化。
您可能会发现您有很多私有方法,它们可能是静态的,但您总是从实例方法(或彼此)调用。在这种情况下,这并不重要。但是,如果您希望真正能够测试您的代码,并可能在其他地方使用它,您可能需要考虑将这些静态方法放在一个不同的、不可实例化的类中。
【讨论】:
方法是否是静态的更多的是设计考虑而不是效率。静态方法属于一个类,非静态方法属于一个对象。如果你有一个 Math 类,你可能有一些静态方法来处理加法和减法,因为这些是与 Math 相关的概念。但是,如果您有一个 Car 类,则可能有一些非静态方法来换档和转向,因为这些方法与特定汽车相关联,而不是一般汽车的概念。
【讨论】:
静态方法的另一个问题是为它们编写单元测试非常痛苦——至少在 Java 中是这样。您不能以任何方式模拟静态方法。有一个post on google testing blog about this issue。
我的经验法则是仅在没有外部依赖项(如数据库访问、读取文件、电子邮件等)时编写静态方法,以使它们尽可能简单。
【讨论】:
请记住,每当您编写静态方法时,您就是在编写一个无法轻易修改其行为的不灵活方法。
您正在编写程序代码,所以如果程序化有意义,那就去做吧。如果不是,它应该是一个实例方法。
这个想法来自an article by Steve Yegge,我认为这是一个有趣且有用的阅读。
【讨论】:
@jagmal 我认为您在某处有一些交叉 - 您列出的所有示例显然都不是静态方法。
静态方法应该完全处理类的抽象属性和概念——它们绝不应该与实例特定的属性相关(如果这样做,大多数编译器都会大喊大叫)。
对于汽车示例,速度、行驶公里数显然与属性相关。在汽车级别考虑时,换档和速度计算是依赖于属性的 - 但考虑从汽车继承的 carModel 类:此时它们可以成为静态方法,因为所需的属性(例如车轮直径)可以定义为该级别的常量。
【讨论】:
在性能方面,C++ 静态方法可能比非虚拟实例方法稍快,因为不需要将“this”指针传递给该方法。反过来,两者都将比虚拟方法更快,因为不需要 VMT 查找。
但是,它很可能正处于噪音之中 - 特别是对于允许优化不必要的参数传递的语言。
【讨论】:
这里有一个关于 why String.Format is static 的相关讨论,其中将突出一些原因。
【讨论】:
将方法设为静态时要考虑的另一件事是,任何能够看到该类的人都能够调用静态方法。而当方法是实例方法时,只有有权访问实例的人才能调用该方法。
【讨论】: