我是一名Java程序员,刚进入企业界。最近我用Groovy和Java开发了一个应用程序。在我编写的所有代码中,都使用了相当多的静态元素。高级技术人员要求我减少使用的静态数据的数量。我在谷歌上搜索过相同的内容,我发现许多程序员都相当反对使用静态变量。
我发现静态变量使用起来更方便。而且我假定它们也是有效的(如果我错了请纠正我),因为如果我必须在一个类中对一个函数进行10,000次调用,我将很高兴使方法静态,并在其上使用直接的class . methodcall(),而不是用10,000个类实例使内存混乱,对吗?
此外,静态减少了对代码其他部分的相互依赖。他们可以作为完美的国家持有者。除此之外,我还发现一些语言(如Smalltalk和Scala)广泛地实现了静态。那么为什么程序员普遍反对静态(尤其是在Java世界中)呢?
PS:如果我对静态数据的假设是错误的,请纠正我。
“静态是邪恶的”这个问题更多的是关于全局状态的问题。一个变量保持静态的适当时间是当它从来没有超过一个状态时;IE工具应该可以被整个框架访问,并且总是为相同的方法调用返回相同的结果,这些都不是静态的“邪恶”。关于你的评论:
我发现静态变量使用起来更方便。我认为他们也很有效率
对于永远不会改变的变量/类,静态是理想和有效的选择。
The problem with global state is the inherent inconsistency that it can create. Documentation about unit tests often address this issue, since any time there is a global state that can be accessed by more than multiple unrelated objects, your unit tests will be incomplete, and not 'unit' grained. As mentioned in this article about global state and singletons, if object A and B are unrelated (as in one is not expressly given reference to another), then A should not be able to affect the state of B.
在良好的代码中,有一些禁用全局状态的例外,例如时钟。时间是全局的,在某种意义上,它改变了对象的状态,而不需要编码关系。
在我看来,你是在问静态变量,但你也在你的例子中指出了静态方法。
静态变量并不是邪恶的——它们被采用为全局变量,就像大多数情况下与最终修饰符结合的常量一样,但正如它所说的,不要过度使用它们。
静态方法又名实用方法。使用它们通常不是一个坏的做法,但主要的问题是它们可能阻碍测试。
作为一个伟大的java项目的例子,使用了大量的静态和做它的正确方式,请看看Play!框架。在SO中也有关于它的讨论。
与静态导入相结合的静态变量/方法也被广泛应用于方便java中声明性编程的库中,如:make it easy或Hamcrest。如果没有大量的静态变量和方法,这是不可能的。
所以静态变量(和方法)很好,但要明智地使用它们!
不。全球国家本身并不邪恶。但我们必须看看你的代码,看看你是否正确使用了它。一个新手很有可能滥用全局状态;就像他会滥用每一种语言特性一样。
全局状态是绝对必要的。我们不能回避全球国家。我们无法避免对全球状态进行推理。-如果我们关心我们的应用程序语义。
那些为了摆脱全局状态而试图摆脱全局状态的人,最终不可避免地会得到一个更复杂的系统——全局状态仍然存在,巧妙地/愚蠢地伪装在许多层间接之下;在解开所有的间接之后,我们仍然需要推理全局状态。
就像Spring的人在xml中大量声明全局状态,并认为它在某种程度上更优越。
@Jon Skeet如果我创建一个对象的新实例,现在你有两件事要考虑——对象内部的状态,以及承载对象的环境的状态。
“静态是邪恶的”这个问题更多的是关于全局状态的问题。一个变量保持静态的适当时间是当它从来没有超过一个状态时;IE工具应该可以被整个框架访问,并且总是为相同的方法调用返回相同的结果,这些都不是静态的“邪恶”。关于你的评论:
我发现静态变量使用起来更方便。我认为他们也很有效率
对于永远不会改变的变量/类,静态是理想和有效的选择。
The problem with global state is the inherent inconsistency that it can create. Documentation about unit tests often address this issue, since any time there is a global state that can be accessed by more than multiple unrelated objects, your unit tests will be incomplete, and not 'unit' grained. As mentioned in this article about global state and singletons, if object A and B are unrelated (as in one is not expressly given reference to another), then A should not be able to affect the state of B.
在良好的代码中,有一些禁用全局状态的例外,例如时钟。时间是全局的,在某种意义上,它改变了对象的状态,而不需要编码关系。
a)关于程序的原因。
如果你有一个小型到中型的程序,其中静态变量Global。Foo被访问,对它的调用通常不知道从哪里来——没有路径,因此也没有时间轴,变量是如何到达这个地方的,它在哪里被使用。现在我怎么知道是谁设置了它的实际值呢?如果我现在修改它,我怎么知道会发生什么呢?我让grep覆盖整个源代码,收集所有访问,知道发生了什么。
如果你知道如何使用它,因为你只是写了代码,问题是看不见的,但如果你试着理解外国代码,你就会明白。
b)你真的只需要一个吗?
静态变量通常会阻止相同类型的多个程序在相同JVM中运行,但它们的值不同。您通常无法预见在哪些情况下您的程序的多个实例是有用的,但是如果它发展了,或者如果它对其他人有用,他们可能会遇到这样的情况,他们想要启动您的程序的多个实例。
只有那些在较长时间内不会被很多人密集使用的或多或少无用的代码才可能适合使用静态变量。