为什么静态变量被认为是邪恶的?| Java Debug 笔记

228 阅读6分钟

本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看活动链接

为什么静态变量被认为是邪恶的?

我是一位Java程序员,对公司领域来说是新手。最近,我已经使用Groovy和Java开发了一个应用程序。我编写的所有代码都使用了大量的静态变量。高级技术人员要求我减少使用的静电数量。我已经在谷歌上搜索了相同的内容,并且发现许多程序员都相当反对使用静态变量。

我发现静态变量更易于使用。而且我认为它们也是有效的(如果我错了,请纠正我),因为如果我必须对一个类中的一个函数进行10,000次调用,我将很高兴使该方法静态化并对其使用直接方法Class.methodCall(),而不是10,000个类的实例使内存混乱,对吗?

而且,静态函数减少了对代码其他部分的相互依赖。他们可以充当完美的国家拥有者。除此之外,我发现在诸如Smalltalk和Scala之类的某些语言中广泛实现了静态方法。那么,为什么在程序员中(尤其是在Java世界中)普遍存在对静态的这种压迫呢?

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

高分回答:

很多的知识点,真的需要写出来才会掌握!!! \color{purple}很多的知识点,真的需要写出来才会掌握!!!{~}

静态变量表示全局状态。这很难推理,也很难测试:如果创建对象的新实例,则可以在测试中推断其新状态。如果我使用的代码使用的是静态变量,则它可能处于任何状态-任何东西都可能对其进行修改。

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

高分回答:

它不是非常面向对象的:某些人可能将静力学视为“邪恶”的原因之一是它们与面向对象的范式相反。特别是,它违反了将数据封装在对象中(可以扩展,隐藏信息等)的原理。静态,按照您描述使用它们的方式,本质上是将它们用作全局变量,以避免处理诸如范围之类的问题。但是,全局变量是过程或命令式编程范例的定义特征之一,而不是“好的”面向对象代码的特征。这并不是说程序范式很糟糕,但是我给您的印象是您的主管希望您正在编写“良好的面向对象的代码”,而您确实想编写“好的程序代码”。

当您开始使用静态方法时,Java中有很多问题并不总是立即显而易见的。例如,如果您的程序的两个副本在同一VM中运行,它们是否会切分静态变量的值并彼此混淆?或在扩展类时会发生什么,可以覆盖静态成员吗​​?您的VM是否因为内存中有大量的静态数据而用完了内存,并且无法为其他所需的实例对象回收该内存?

对象生存期:此外,静态变量的生存期与程序的整个运行期相匹配。这意味着,即使您已经完成使用类的工作,所有这些静态变量的内存也无法被垃圾回收。例如,如果您使变量成为非静态变量,并且在main()函数中创建了类的单个实例,然后在完成这10,000次调用后要求您的类执行特定函数10,000次。 ,然后删除对单个实例的引用,所有静态变量都可能被垃圾回收并重新使用。

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

其他选项:如果效率是您最关心的问题,那么解决速度问题可能还有其他更好的方法,而不是只考虑调用通常比创建快的优点。考虑是否需要在任何地方使用瞬态或挥发性调节剂。为了保留内联的能力,可以将方法标记为final而不是static。可以将方法参数和其他变量标记为final,以允许基于有关可更改这些变量的假设的某些编译器优化。一个实例对象可以多次重用,而不是每次都创建一个新实例。通常,应该为应用程序打开兼容的优化开关。也许应该对设计进行设置,以使10,000个运行可以成为多线程并利用多处理器内核。如果可移植性是'请注意,也许本机方法会比静态方法获得更快的速度。

如果由于某种原因您不想要一个对象的多个副本,则使用单例设计模式与静态对象相比,具有优势,例如线程安全(假设您的单例代码编写正确),允许延迟初始化,确保对象在使用时已正确初始化,子类化,在测试和重构代码方面的优势,更不用说,如果您在某个时候改变了主意,只想要一个对象的实例,那么删除代码以防止重复的实例要比重构所有静态变量代码以使用实例变量要容易得多。我以前不得不这样做,这很不好玩,而且您最终不得不编辑更多的类,这增加了引入新的错误的风险……如此之好,是第一次将它们设置为“正确”的情况,即使它看起来有其缺点。为我,如果您决定自己需要一些东西的多个副本,那么可能需要的返工可能是尽可能不频繁使用静态变量的最令人信服的原因之一。因此,我也不同意您的说法,即静态会减少相互依赖性,如果您有很多可以直接访问的静态,而不是“知道如何操作”的对象,那么我认为您最终将获得更多的耦合代码。东西”。

文章翻译自kgs4h5t57thfb6iyuz6dqtun5y-ac4c6men2g7xr2a-stackoverflow-com.translate.goog/questions/7…

作者建议:我在这个文章中,提到了线程池ThreadPoolExecutor里面的静态内部类worker和内部类拒绝策略,以及静态内部类实现的单例模式和java源码中url模板类使用的静态内部类实现的单例模式

Java中的静态类?

欢迎关注我的专栏StackOverFlow,我会筛选优质的问答,面试常考!!! \color{red}欢迎关注我的专栏StackOverFlow,我会筛选优质的问答,面试常考!!!{~}

有最新、优雅的实现方式,我也会在文末写出我对本问答的见解 \color{red}有最新、优雅的实现方式,我也会在文末写出我对本问答的见解{~}

真心感谢帅逼靓女们能看到这里,如果这个文章写得还不错,觉得有点东西的话

求点赞👍 求关注❤️ 求分享👥 对8块腹肌的我来说真的 非常有用!!!

如果本篇博客有任何错误,请批评指教,不胜感激 !❤️❤️❤️❤️