java - 为什么虎书的符号表中要字符串intern?

标签 java string-interning

在第 5.1.4 章中,Java 中的现代编译器实现:

public class Symbol {
  private String name;
  private Symbol (String n) { name = n; }
  private static java.util.Dictionary dict = new java.util.Hashtable();

  public String toString() { return name; }

  public static Symbol symbol(String n) {
    String u = n.intern();
    Symbol s = (Symbol)dict.get(u);
    if (s == null) { s = new Symbol(u); dict.put(u, s); }
    return s;
  }
}

我不明白为什么在这里使用 string intern,因为 Hashtable 使用 key.equals(...) 来检查身份。

能告诉我原因吗?谢谢!

最佳答案

在编程中存在着很多“智慧”、“谣言”、“魔法”或“迷信”。

正如 @RealSkepic 指出的,在 Java 7u4 之前,String.substring 将使用原始字符串的一部分,而不是复制该部分。虽然这在许多情况下提高了性能,但可能会导致内存泄漏。使用 intern() 是避免这种情况的一种方法,尽管它可能会产生自己的内存清理问题,这并不理想。使用 new String(oldString) 是另一种方法,但您现在不需要这样做。

人们经常出于“性能原因”尝试一些东西,但不知道如何测试它,或者只是不检查它是否真的有帮助。我时常这样做,尽管我知道要避免这样做,因为它常常是不正确的,或者只是让代码变得困惑。

很可能作者发现了一种情况,或者听说有人通过使用String.intern()节省了大量内存,并且在特定情况下,它可以做到这一点,但它不像仙尘只要你施展一点表演魔法,一切都会变得更好。大多数这些晦涩难懂的代码优化技巧仅适用于非常特定的用例。

一个类似的例子是人们在多线程中使用锁或线程安全集合。在周围撒上足够多的东西,程序似乎可以阻止错误,但你并没有真正解决问题,只是让当偶然发生的变化和你的错误再次出现时更难发现。

关于java - 为什么虎书的符号表中要字符串intern?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36302292/

相关文章:

java - 使用 elasticSearch 和 Spring Boot 创建 bean 时出错

java - JNA - 获取 OSX 上所有可见的窗口句柄

java - 可能已经分配了常量变量

javascript - 常见的 JavaScript 实现是否使用字符串驻留?

java - Oracle上执行的executeBatch()是否按顺序执行?

java - 被 Java 中的多个缩进 if 语句搞糊涂了

c# - serializer.Deserialize<T>() 上的字符串实习生

c++ - 如何在 C 或 C++ 中进行字符串实习?

java - 何时在字符串文字上使用 intern()

c# - c# 6.0 nameof() 结果是否被实习?