java - 静态变量为何被视为罪恶?

  显示原文与译文双语对照的内容

我是一个对企业世界来说是新的Java程序员。 最近我使用 Groovy 和Java开发了一个应用程序。 所有的代码我都使用了相当多的静力学。 高级技术人员要求我减少使用的静态数。 我在谷歌上做了同样的事情,我发现很多程序员都在使用静态变量。

我发现静态变量更方便使用。 采用的类,right,和我再假设他们是有效太( 如果我错了请纠正我) 10,000实例,因为要我列出 10,000调用到类中的一个函数,我将是高兴的在上面做静态的,将使用简单 class.methodCall()的方法,而不是将内存的情形?

此外,静态减少了代码其他部分的inter-dependencies 。 他们可以充当完美的状态持有者。 添加到这一点,我发现静态在一些语言如Smalltalk和 Scala 中得到了广泛的实现。 那么为什么在程序员的( 尤其是在Java世界中) 中对静态的这种压抑?

PS: 如果我对静态的假设有误,请更正我。

时间:

它不是非常面向对象的: 静力学可能会被有些人认为是"邪恶"一个原因是它们是相反的object-oriented范式 。 特别是,它违反了将数据封装在对象( 可以扩展,信息隐藏等) 中的原则。 有了像scope,静校正的问题,在你描述的是使用它们的方式,本质上是把这种书当做全局变量为了避免 dealing. 但是,全局变量的定义特征之一是面向过程式或者命令式的编程范式,而不是一种特征"好"对象的代码。 这不是你们当前的程序上的范式是错误的,但我有这样的印象你的主管希望你面对是你在编写"良好的面向对象代码"和真正想要写"良好的过程代码"。

当你开始使用不总是很明显的静态时,Java中有很多 gotchyas 。 现状的人们每个 other, 。例如如果你有两个拷贝你的程序并且可以自由运行在同一个 VM,将他们shre了静态值的变量? 或者当扩展类时,你可以重写静态成员? objects,于另外需要的相关实例你的虚拟机是否用尽内存,因为你有疯狂的静力学及数字的内存不能被回收?

对象生存期: 此外,静校正使它的生存期相匹配的整个程序的运行时间。 在所有那些静态变量不能被垃圾collected,这意味着,就算你不再操作你的类里的内存。 如果,例如相反,变量non-static你就成功了,和你的main() 函数在进行你的类,然后问你类的单个实例来执行某个函数,一旦那些 10,000 10,000次调用完成后,和你删除了你的引用到,使用单实例,所有静态变量可以被垃圾回收机制回收和重复使用。

在被 usable, 也防止将某些 re-use: 静态方法,静态方法不能被用来实现一个接口中,这样可以防止某些面向对象 features.

其他选项: 如果效率是你首要关心的,可能有其他更好的方法来解决加速问题并未完全考虑只调用是通常的速度比的优点开发的。 考虑在任何地方是否需要瞬态或者volatile修饰符。 为了保持内联的能力,方法可以被标记为 final 而不是静态的。 什么上假设可以改变这些参数和其他变量可以标 final variables,方法以允许某些编译器 optimiazations based. 实例对象可以多次重用,而不是每次创建一个新实例。 可能有compliler优化开关应该在一般情况下打开。 比如,设计时应建立以使 10,000运行,可以被multi-threaded和充分利用multi-processor内核。 如果portablity不是一个问题,也许本机方法会让你的速度比你的静态方法更好。

如果因为某些原因你不希望某个对象的多个副本的这个单例设计模式通过静态对象都有优点如thread-safety可以保证使用的对象已经被正确初始化,当它在测试和重构你的代码更不要说如果在某个时刻你改主意了,想只想分对象的一个实例的实例要容易得多删除了代码以避免重复,要比重构所有代码以使用你的静态变量,实例变量。 我还得先修改再,不太好玩,而且你最终必须编辑大量更多的类,它可以增加所带来的新的漏洞而且绝对更好的风险要部署好了"右边"第一次,即使它似乎是它有它的缺点。 对我来说,所需的re-work当你决定的情形吧你需要的多个副本某事可能是最吸引人的原因之一为使用静力学应该尽可能少。 我也会不同意你的声明静校正在itself,上,从而减少 inter-dependencies,我认为你将会遇到代码来就更多的耦合如果具有大量的静态分析,可以直接上网,而不是一个对象,

不,全局状态本身不是邪恶的。 但是我们必须看到你 正确的代码,看是否使用它。 新手滥用全局状态很可能,就像他滥用所有语言功能一样。

全局状态是绝对必要的。 我们不能避免全局状态。 我们不能避免对全局状态的推理。 - 如果我们关心我们的应用程序语义。

解包裹所有的indirections,后为为了便于它,最终,不可避免地尝试摆脱全局状态的人提供了一个更加复杂的系统- 待在那儿到时巧妙地和全局状态/idiotically伪装下许多层次的间接寻址) ;我们仍然需要原因,.有关全局状态

就像 spring 用户大量声明xml的全局状态,并认为它是优越的。

@Jon 双旋翼 if I create a new instance of an object 你现在拥有了两个东西,来思考- 在对象的状态的,和环境状态的托管对象。

在我看来,几乎没有性能,它是关于设计。 我不认为静态方法的使用是错误的,而不是使用静态变量( 但我想你实际上是在谈论方法调用) 。

它只是关于如何隔离逻辑并给它一个好地方。 有时候,使用静态方法是合理的,java.lang.Math 是一个很好的例子。 我想当你给你的大多数类命名 XxxUtil 或者 Xxxhelper 时,你最好重新考虑你的设计。

...