什么时候不在Java中使用static关键字?

29 java static static-methods

什么时候在方法签名上使用Java中的static关键字被认为是不好的做法?如果方法基于某些参数执行函数,并且不需要访问非静态的字段,那么您是否总是希望这些类型的方法是静态的?

Kev*_*ion 48

您将在大型Java应用程序中遇到的两个最大的弊端是

  • 静态方法,除了那些纯函数*
  • 可变静态字段

这些破坏了代码的模块性,可扩展性和可测试性,我意识到我无法在这个有限的时间和空间中说服你.

*"纯函数"是任何不修改任何状态的方法,其结果仅取决于提供给它的参数.因此,例如,任何执行I/O(直接或间接)的函数都不是纯函数,但Math.sqrt()当然是.

关于纯粹功能(自我链接)的更多blahblah以及为什么要坚持它们.

我强烈建议您支持"依赖注入"编程风格,可能由Spring或Guice等框架支持(免责声明:我是后者的合着者).如果你这样做的权利,你会基本上是永远需要可变静止状态还是非纯静态方法.

  • 哦,哦,我不知道这个Eric Lippert,所以现在我很偏执,他是某种混蛋.:)这是处理I/O的假设静态方法的处理:没关系.哦,但调用它的代码?那段代码不好.该代码很难测试.由于它无法控制地执行I/O,我的测试需要确保以特定方式设置程序外部的状态.现在我依赖于那个设置,如果我忘了它,我可能会好的,这取决于我的测试运行的顺序,以及我是否忘记稍后恢复原始状态......等等. (8认同)
  • 对于其他所有人来说:表达对凯文的不同意见就像表达了对Eric Lippert的不同意见.我感到紧张,几乎可以用一根巨大的线索击中头部.请温柔,凯文...... (4认同)
  • 所以你反对在静态方法中做任何I/O,即使它对对象的状态没有任何作用,它是一个密封的类,你是否传递了作为参数执行IO的对象?我同意它仍然不是纯粹的,但我不知道如何使它成为一个实例方法在这种情况下有所帮助. (2认同)

Jon*_*eet 33

可能不希望它是静态的一个原因是允许它在子类中被覆盖.换句话说,行为可能不依赖于对象内的数据,而是取决于对象的确切类型.例如,你可能有一个通用的集合类型,有isReadOnly这将财产归还false在始终可变集合,true在始终不变的集合,而在其他依赖于实例变量.

但是,根据我的经验,这种情况非常罕见 - 通常应明确说明.通常我会创建一个不依赖于任何对象状态静态的方法.

  • 静态不是关于访问成员字段.它是关于类语义的.如果方法适用于类的实例,则它不能是静态的.在您的情况下,它是您的集合实例是只读的,而不是类本身,因此该函数必须是非静态的.Static实际上是关于类方法,用于工厂或实用程序函数. (13认同)
  • 请留下我真正输入评论的时间;-) (2认同)

Pas*_*ent 24

一般来说,我更喜欢实例方法,原因如下:

  1. 静态方法使测试变得困难,因为它们无法替换,
  2. 静态方法更加面向程序.

在我看来,静态方法对于实用程序类(例如StringUtils)是可以的,但我更愿意尽可能避免使用它们.

  • 关于2:OO是一个工具,而不是目标. (12认同)
  • +1尤其适用于测试提及.我们正在使用JUnit,并且需要在模拟对象中重写方法. (2认同)