为什么静态变量被视为邪恶?

我是一名Java程序员,对企业界来说是新手。 最近我开发了一个使用Groovy和Java的应用程序。 所有通过我写的代码使用了相当多的静态数据。 高级技术人员要求我减少使用的静态数量。 我一直在搜索,我发现很多程序员都反对使用静态变量。

我发现静态变量更方便使用。 而且我认为它们也很高效(如果我错了,请纠正我),因为如果我必须对类中的函数进行10,000次调用,我会很乐意使该方法成为静态的并使用简单的Class.methodCall()而不是使用该类的10,000个实例混淆内存,对吧?

而且,静态减少了对代码其他部分的相互依赖关系。 他们可以充当完美的国家持有者。 除此之外,我发现静态在Smalltalk和Scala等语言中得到了广泛的应用。 那么为什么这种压制静态技术在程序员中普遍存在(特别是在Java领域)呢?

PS:如果我对静力学的假设是错误的,请纠正我。


静态变量代表全局状态。 这很难推理和难以测试:如果我创建一个对象的新实例,我可以在测试中推断它的新状态。 如果我使用使用静态变量的代码,它可能处于任何状态 - 任何事情都可能正在修改它。

我可以继续相当长一段时间,但要想到的更大的概念是,事物的范围越紧密,就越容易推理。 我们善于考虑小事情,但如果没有模块化,就很难推断一百万行系统的状态。 这适用于各种各样的东西,顺便说一下 - 不仅仅是静态变量。


它不是非常面向对象的:一些人认为静态可能被认为是“邪恶”的一个原因是它们违背了面向对象的范式。 特别是,它违反了数据封装在对象中的原则(可以扩展,信息隐藏等)。 以您使用它们的方式描述的静态方法基本上是将它们用作全局变量,以避免处理像范围这样的问题。 然而,全局变量是过程式或命令式编程范式的决定性特征之一,而不是“良好”面向对象代码的特征。 这并不是说程序模式是不好的,但是我的印象是你的主管期望你写“好的面向对象的代码”,而你真的想写出“好的程序代码”。

当你开始使用并不总是显而易见的静态的Java时,Java中有很多的变体。 例如,如果你的程序有两个副本在同一个虚拟机上运行,​​他们是否会把这个静态变量的值弄乱并混淆对方的状态? 或者当你扩展类时会发生什么,你可以重写静态成员吗​​? 您的VM是否因内存不足而导致内存不足,并且该内存无法回收用于其他所需的实例对象?

对象生命周期:另外,静态的生命周期与程序的整个运行时间相匹配。 这意味着,即使完成了使用类的操作,所有这些静态变量的内存也不会被垃圾收集。 例如,如果您将变量设置为非静态变量,并且在您的main()函数中创建了一个类的单个实例,然后要求您的班级在完成10,000次调用后执行特定功能10,000次,并且你删除了你对单个实例的引用,你所有的静态变量都可以被垃圾收集和重用。

防止某些重用:另外,静态方法不能用于实现接口,所以静态方法可以防止某些面向对象的功能可用。

其他选择:如果效率是您最关心的问题,那么可能还有其他更好的方法来解决速度问题,而不仅仅考虑调用的优势通常比创建更快。 考虑是否需要瞬态或挥发性修饰符。 为了保持被内联的能力,一个方法可以被标记为final而不是静态的。 方法参数和其他变量可以被标记为最终的,以允许某些编译器优化基于关于可以改变这些变量的假设。 实例对象可以多次重复使用,而不是每次都创建一个新实例。 一般而言,应用程序可能会打开应用程序优化开关。 也许,应该设计设计,以便10,000次运行可以是多线程的,并且可以利用多处理器内核。 如果可移植性不是问题,那么也许本地方法会让你的速度超过静态。

如果由于某种原因,你不希望多个副本的对象,单体设计模式,比静态对象,如线程安全(假设你的单例编码得好)有优势,允许延迟初始化,保证对象已正确在使用时进行初始化,子分类,测试和重构代码的优点,更不用说,如果在某些时候您改变主意只想要一个对象的实例,则更容易移除代码以防止重复实例比重构所有的静态变量代码来使用实例变量更重要。 我之前必须这样做,它并不好玩,最终你不得不编辑更多的课程,这增加了你引入新bug的风险......更好地设置第一次“正确”的事情,即使它看起来有缺点。 对于我来说,如果你决定采取多种方式复制某些东西,那么需要重新进行工作,这可能是最不经常使用静态的最令人信服的理由之一。 因此,我也不同意你的陈述,即静态减少了相互依赖关系,如果你有很多可以直接访问的静态信息,而不是一个“知道该怎么做”的对象,我认为你最终会得到更加耦合的代码东西“本身。


邪恶是一个主观的术语。

您不会在创建和销毁方面控制静态。 他们住在程序装载和卸载的要求下。

由于静态存在于一个空间中,所有希望使用它们的线程都必须通过必须管理的访问控制。 这意味着计划更加耦合,这种变化更难以设想和管理(就像J Skeet所说的那样)。 这会导致隔离变更影响的问题,从而影响测试的管理方式。

这是我与他们的两个主要问题。

链接地址: http://www.djcxy.com/p/13279.html

上一篇: Why are static variables considered evil?

下一篇: Behaviour of CopyOnWriteArrayList