我正在开发一个Enterprise Java应用程序,它本质上是一个HTTP服务器。在那里,我需要使用一些常量和实用函数来解析,文件I / O等。我已经为此目的使用了静态方法和变量,但是有人向我指出,为此目的使用静态是一个糟糕的选择,因为从表现和记忆的观点。
虽然我不同意这个论点,但我也没有看到任何其他选择。即使我将它们转换为实例方法,并通过单例实例进行访问,实例也会被一些静态函数访问。
所以,我想知道这是不是真的有问题。如果是,修复它的最佳方法是什么?
提前致谢。
答案 0 :(得分:4)
你说得对,最终一切都是从静态main()
方法运行的。并且许多功能适合于静止,例如,简单的方法,如java.lang.Math
上的方法。速度和内存使用都不是问题 - 静态方法不会占用更多内存或运行速度比任何其他方法慢。在内部,它与任何其他方法完全相同,但是在类实例上定义并运行,而不是在类的实例上运行。
我在静态方法中发现的一个问题是,在一些特定的假设(例如目录所在的位置)中很容易无意中滑动,这使得在其他地方重用该函数变得更加困难。测试代码也变得更加困难。当您进行单元测试时,您通常希望能够在不进行*耗时的情况下进行测试)I / O - 例如通过模拟或删除I / O部分。如果你的方法不允许,那就更难了。单例类可能会导致类似的测试困难。
静态方法倾向于导致功能或程序,而不是面向对象的代码。我发现静态方法可用作对象的丰富域模型之上的“语法糖”的功能层。
还值得一提的是,现有的实用程序类很多,例如Apache Commons IO,Google Guava等。它们编写得很好,使用频繁且经过充分测试。你可以考虑在重新发明轮子之前先看一下它们。
答案 1 :(得分:2)
首先,问问自己为什么要使用静态方法或单例?当您计划使用静态方法或单例时,您需要有理由。在某些情况下,这可能是最好的方式。
有两种类型的“静态方法”:
有些人倾向于过度使用静态方法 - 尤其是习惯于程序语言的人。消除这种思维的最好方法是彻底了解面向对象的原则和实践。我认为可以帮助很多东西的是TDD - 静态方法很难测试,使用TDD强制你创建“可测试”代码,这也是一个设计合理的代码。
答案 2 :(得分:1)
实际上,我可以看到使用静态方法实现实用功能的更多好处
private
,它与标记为final
的类一起明确表示此类是库import static SomeClass.someMethod;
的方法,因此您不必反复编写类名答案 3 :(得分:1)
但有人向我指出,从性能和内存的角度来看,为此目的使用静态是一个糟糕的选择
这是非精神或迷信或两者兼而有之! 向他们询问静态方法较慢的证据,或在其他情况相同的情况下使用更多内存。
两种方法(不惜一切代价避免静电/使一切都静止)都很糟糕。
答案 4 :(得分:1)
你测试你的代码吗?
通过测试,static
的不受欢迎变得明显:
Util
类打开一个文件,那么你必须在测试时拥有该文件。Util
类(然后更改CDI容器注入的类)来制作这些方法的更专业版本。除非构建一个不太可能改变的真实实用程序库(例如Apache Commons),否则执行使用实例方法并使用单例。
将来选择您的代码并需要更改它的人将会感谢您。
跟进:Static Methods are Death to Testability
1:实际上,您可以使用PowerMock等工具模拟static
方法。但是它们太过侵入性,而且它们产生的测试非常脆弱,它们错过了测试的目的。这种工具的需求是代码库中问题的有力指标。 (及时,这些工具对遗留系统测试很有用。)
答案 5 :(得分:0)
简而言之,除非这个Util
类是巨大的,否则这不会带来大灾难。你不应该忽略静态类的使用,因为它们很有用,而且看起来也好多了。
MyFileReader.readFile("C:/file.txt");
看起来比:
更好MyFileReader mfr = new MyFileReader();
mfr.readFile("C:/file.txt");
而且,如果将其更改为实例方法,则每次要使用它时都必须创建对象。我相信这也会影响性能。您的应用程序将使用更多内存,但如果类是合理的大小(如果不是它应该被拆分),那么你应该没问题。
答案 6 :(得分:0)
使用静态方法实际上是一个性能问题,因为它在编译时解决了。 从记忆的角度来看,我也不同意这一点。 对于静态常量,一旦使用它们就会加载它们所需的时间。 对于静态方法,它与Instance方法相同,除非Instance是一个名为“this”的隐藏。
但是静态方法的使用位置是最重要的。如果您的方法确实需要执行一些可能在不同场景中使用的常用功能,那么我会选择静态方法。 在你的情况下,你是对的,静态方法用于实用功能。 真的需要检查文件I / O操作它做了什么,如果某种上下文保存在类级别进行这样的操作,那么这是不可取的。
实用程序功能实际上在许多地方使用,在这种情况下使用Singleton会引入位性能问题。