Java 为什么要在老虎书的符号表中列出实习生?

Java 为什么要在老虎书的符号表中列出实习生?,java,string-interning,Java,String Interning,在第5.1.4章中,Java的现代编译器实现: 我不明白为什么在这里使用字符串intern,因为哈希表使用key.equals(…)来检查身份 你能告诉我原因吗?谢谢 编程中有很多“智慧”、“谣言”、“魔法”或“迷信” 正如@RealSkepic指出的,在Java7U4之前,String.substring将使用原始字符串的一部分,而不是复制该部分。虽然这在许多情况下提高了性能,但可能会导致内存泄漏。使用intern()。使用newstring(oldString)是另一种方法,但现在不需要这样

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

我不明白为什么在这里使用字符串intern,因为
哈希表
使用
key.equals(…)
来检查身份


你能告诉我原因吗?谢谢

编程中有很多“智慧”、“谣言”、“魔法”或“迷信”

正如@RealSkepic指出的,在Java7U4之前,String.substring将使用原始字符串的一部分,而不是复制该部分。虽然这在许多情况下提高了性能,但可能会导致内存泄漏。使用
intern()。使用
newstring(oldString)
是另一种方法,但现在不需要这样做

人们经常为了“性能原因”而尝试,但不知道如何测试,或者只是不检查它是否真的有用。我经常这样做,即使我知道应该避免这样做,因为它经常是不正确的,或者只是让代码变得混乱

作者很可能发现了一种情况,或者听说有人通过使用
String.intern()
节省了大量内存,在特定情况下,它可以做到这一点,但这不像仙女尘那样,你撒了一点性能魔法,一切都会更好。这些模糊的优化代码的技巧大多只适用于非常特定的用例


类似的例子是当人们在多线程中使用锁或线程安全集合时。如果在程序中使用了足够多的方法,程序可能会停止一个错误,但你还没有真正解决问题,只是让它更难发现什么偶然的变化和错误再次出现。

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

正如@RealSkepic指出的,在Java7U4之前,String.substring将使用原始字符串的一部分,而不是复制该部分。虽然这在许多情况下提高了性能,但可能会导致内存泄漏。使用
intern()。使用
newstring(oldString)
是另一种方法,但现在不需要这样做

人们经常为了“性能原因”而尝试,但不知道如何测试,或者只是不检查它是否真的有用。我经常这样做,即使我知道应该避免这样做,因为它经常是不正确的,或者只是让代码变得混乱

作者很可能发现了一种情况,或者听说有人通过使用
String.intern()
节省了大量内存,在特定情况下,它可以做到这一点,但这不像仙女尘那样,你撒了一点性能魔法,一切都会更好。这些模糊的优化代码的技巧大多只适用于非常特定的用例


类似的例子是当人们在多线程中使用锁或线程安全集合时。如果这样做的话,程序可能会停止一个错误,但你还没有真正解决这个问题,只是让你更难发现什么偶然的变化,你的错误再次出现。

我希望你知道
String#intern
的作用。简单地说,它将把给定的字符串添加到string类维护的字符串池中,如果它已经不是字符串池的一部分,或者如果该字符串已经是字符串池的一部分,则返回该对象。因此,字符串池中只有字符串的这个特定值的副本


它的意思是当我们执行aString.intern()
时,这总是放在映射中,下一次当从映射中获取另一个字符串.intern()
时,在比较本身中等于将返回true。这将避免迭代整个字符串以验证相等性。如果映射中存储的字符串可能很大,并且映射将经常被搜索(获取或包含操作),那么这将证明是一个巨大的性能改进。

我希望您知道
String\intern
的作用。简单地说,它将把给定的字符串添加到string类维护的字符串池中,如果它已经不是字符串池的一部分,或者如果该字符串已经是字符串池的一部分,则返回该对象。因此,字符串池中只有字符串的这个特定值的副本


它的意思是当我们执行aString.intern()时,这总是放在映射中,下一次当从映射中获取另一个字符串.intern()时,在比较本身中等于将返回true。这将避免迭代整个字符串以验证相等性。如果存储在映射中的字符串可能很大,并且映射将经常被搜索(获取或包含操作),那么这可能会大大提高性能。

我推测这是为了节省内存。我想不出任何原因。也许他们认为这样可以节省内存。。。但实际上我认为它会占用更多的内存。@StephenC我同意你的看法。:-)我想这是为了保存记忆。我想不出任何理由。也许他们认为这样可以节省内存。。。但实际上我认为它会占用更多的内存。@StephenC我同意你的看法。:-)我不完全确定。我认为这个类可能是整个编译框架的一部分。您可以通过解析字符串中的数据来使用它。它也非常古老(没有泛型),因此,它来自于
子字符串
使用原始
字符串
的整个支持数组的时代。他们可能会担心保留原来的巨大数组,或者用于符号的字符串可能会保存在一个单独的数据结构中,可能会重复多次。我不完全确定。我认为这个类可能是整个编译框架的一部分。您可以通过解析一些数据来使用它
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;
  }
}