当我处理遗留代码并运行 StringBuffer 实例时,我通常将它们替换为 StringBuilder 实例。虽然可以从这个更改中获得性能优势,但我经常在我知道对性能影响不大的地方进行更改。我觉得除了潜在的性能优势之外,出于各种原因值得进行更改。 很少有理由不选择 StringBuilder
而不是 StringBuffer
(API 期望是最常见的例外)并且 $ 中的代码误导并为 Java 新手提供了一个不好的例子。
在 The Pragmatic Programmer: From Journeyman to Master 一书中,Andy Hunt 和 David Thomas 讨论“修复代码中的小问题,即‘破窗’的重要性。 ” Jeff Atwood 在破窗理论一文中谈到了这个主题,最近在软件腐烂、熵和破窗理论和一文中也提到了这个问题不要留下破窗。 StringBuffer
的存在意味着代码中的陈旧性。实际上,StringBuffer
的使用可能不是“破窗”,而是一个非常老旧、漏水的单窗格窗口,应该用现代的、充满活力的-高效的双窗格窗口。
我发现 Peter Lawrey 最近的博文 StringBuffer, and how hard it to get ridge of legacy code 是对 StringBuffer
< 其他含义的有趣解读/code> 仍然存在于代码中。 Lawrey 引用了 StringBuffer 类 Javadoc 文档的最后一段,“从 JDK 5 开始,这个类已经补充了一个为单线程使用而设计的等效类,StringBuilder。通常应优先使用 StringBuilder 类,因为它支持所有相同的操作,但速度更快,因为它不执行同步。” Lawrey 然后使用简单的 Java 方法和 jmap 来证明 $ 的实例仍然在 JDK 提供的类和库中使用,甚至晚至 Java 8。
Lawrey 指出,在引入“直接替换”StringBuffer
十多年后,频繁使用的 Java 代码中出现了 StringBuilder
,这证明了它是多么困难“清理遗留代码。” Lawrey 的完整总结指出,“在启动时使用 StringBuffer
没有太大区别,但考虑到它有一个众所周知的替代品,它仍在使用,即使在十多年的新功能中也是如此后来表明清理遗留代码或改变思维以让人们使用最佳实践库是多么困难。”
我决定在使用 Java 8 Update 121 编译时以及使用最新版本的 OpenJDK 9 编译时尝试 Lawrey 的最简单示例之一。我(稍微)将 Lawrey 的示例改编为简单的“主”类列表接下来显示。
主.java
import java.io.IOException; /** * (Slightly) adapted class from blog post * "StringBuffer, and how hard it is to get rid of legacy code" at * https://vanilla-java.github.io/2017/04/13/String-Buffer-and-how-hard-it-is-to-get-rid-of-legacy-code.html */ public class Main { /** * Main function that instantiates this Java "application" and does nothing * else until "ENTER" is pressed. */ public static void main(final String[] args) throws IOException { System.out.println("Waiting [press ENTER to exit] .."); System.in.read(); } }
以下屏幕快照显示了使用 jcmd 及其 -all
选项(包括检查中无法访问的对象)的输出,以显示 StringBuffer
和 $ 在针对三个不同版本的 Java(Java 8 Update 102、Java 8 Update 121、和 OpenJDK 9.0 ea+164)。 jcmd 的执行是在 PowerShell 中执行的,因此 Select-String 的使用方式类似于 grep 在 Linux 中的使用方式。
虽然使用 Java 8 版本编译和执行的类版本具有 StringBuffer
实例,但使用 Java 9 编译和执行的版本只有 StringBuilder
实例。它看起来像 JDK-8041679(“在核心库类中用 StringBuilder 替换 StringBuffer 的使用”)和 JDK-8043342(“在核心库类中用 StringBuilder 替换 StringBuffer 的使用”)加密代码”)已经达到了预期的效果。
标签2: Java教程地址:https://www.cundage.com/article/jcg-implications-presence-stringbuffer.html