代码之家  ›  专栏  ›  技术社区  ›  Dan

Java如何在引擎盖下实现字符串的FLUZY模式?

  •  16
  • Dan  · 技术社区  · 14 年前

    如果有两个字符串的实例,它们是相等的,那么在Java中它们将共享相同的内存。这是如何在引擎盖下实现的?

    编辑:我的应用程序使用大量的字符串对象,其中许多对象是相同的。使用JavaString常数池的最佳方法是什么,以避免创建自定义的FROUTWORD实现?

    7 回复  |  直到 14 年前
        1
  •  6
  •   meriton    14 年前

    查看的源代码 java.lang.String (整个Java API的源代码是JDK的一部分)。

    总结:字符串包装 char[] . 这种支持 字符[] 从不修改。这样既不泄漏也不捕获 字符[] 在外面 String 班级。但是,有几个 Strings 可以共享相同的 字符[] (见实施 String.substring )

    正如其他答案中所解释的,也有实习的机制。

        2
  •  12
  •   matt b    14 年前

    如果有两个字符串的实例,它们是相等的,那么在Java中它们将共享相同的内存。

    这实际上不是100%正确。

    This blog post is a decent explanation 为什么会这样,以及 字符串常量池 是。

        3
  •  6
  •   Bill the Lizard Hacknightly    14 年前

    字符串文字在Java中被嵌入,所以实际上只有一个字符串对象具有多个引用(当它们相等时,情况并不总是如此)。参见java.net文章 All about intern() 了解更多详细信息。

    还有一个很好的例子/解释 3.10.5 String Literals 在jl中,我们讨论了何时将字符串进行约束以及何时将字符串进行区分。

        4
  •  4
  •   cletus    14 年前

    这是不必要的。例子:

    String s1 = "hello";
    String s2 = "hello";
    System.out.println(s1 == s2); // true
    

    但是:

    String s1 = new String("hello");
    String s2 = new String("hello");
    System.out.println(s1 == s2); // false
    

    现在第二种形式是不鼓励的。有些人(包括我)认为 String 甚至不应该有公共构造函数。更好的版本是:

    String s1 = new String("hello").intern();
    String s2 = new String("hello").intern();
    System.out.println(s1 == s2); // true
    

    显然,你不需要为一个常量做这个。 . 这是说明性的。

    重要的是,如果你通过了 或者从你不能依赖的函数中获取一个 存在 典范的 . 一 典范的 Object 满足此等式:

    a.equals(b) == b.equals(a) == (a == b)
    

    对于非 null 实例 a , b, 给定的 Class .

        5
  •  3
  •   Community miroxlav    7 年前

    要回答您编辑的问题,Sun JVM有一个 -XX:+StringCache 选项,在我的观察中,它可以显著减少大量字符串应用程序的内存占用。

    否则,你可以选择把你的弦绑起来,但我会小心的。非常大且不再被引用的字符串在JVM的生命周期中仍将使用内存。

    编辑(响应注释):我首先从 here :

    -xx:+stringcache启用常用分配字符串的缓存。

    Tom Hawtin 描述一些缓存类型以改进一些基准。当我把它放在想法上时,我的观察是内存足迹(在一次完整的垃圾收集之后)会因为没有它而下降。它不是一个文档化的参数,实际上可能只是为了优化一些基准。我的观察是它有帮助,但我不会基于它构建一个重要的系统。

        6
  •  1
  •   Juha Syrjälä    14 年前

    有两件事要小心:

    1. 不要使用 new String("abc") 构造函数,只需使用文本 "abc" .
    2. 学会使用 intern() 字符串类中的方法。尤其是在将字符串连接在一起或将char array/byte array/etc转换为字符串时。

    intern() 始终返回合并的字符串。

        7
  •  0
  •   Jason    14 年前

    如果相同的字符串来自一组固定的可能值,那么在这里需要一个类型安全枚举。它不仅会减少字符串的数量,而且会使应用程序更加可靠。您的整个应用程序将知道这个字符串附加了语义,甚至可能是一些方便的方法。

    我最喜欢的优化总是那些可以被认为是生成代码的优化。 更好的 不仅仅是更快。10次中有9次,用具体类型替换字符串会导致代码更加正确和自我记录。