JVM - String Interning

String interning(字符串拘留?),是一项把相同字符串值只保存一份copy的方法,比如 "abc""abc"虽然是两个字符串,但是因为其值相同,所以只存留一份copy。String interning能够使得处理字符串的任务在时间上或空间上更有效率。不同字符串值保存在所谓string intern pool里。

Java语言规定所有字符串字面量(string literals)和所有结果为字符串的常量表达式(string-valued constant expression)都被自动interned。或者也可以通过调用String#intern()方法来手动interned。而interened字符串具有这个特性:当且仅当a.equals(b)==true,那么a.intern() == b.intern()

下面是一个例子来说明:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package testPackage;
class Test {
    public static void main(String[] args) {
        String hello = "Hello", lo = "lo";
        System.out.print((hello == "Hello") + " ");
        System.out.print((Other.hello == hello) + " ");
        System.out.print((other.Other.hello == hello) + " ");
        System.out.print((hello == ("Hel"+"lo")) + " ");
        System.out.print((hello == ("Hel"+lo)) + " ");
        System.out.println(hello == ("Hel"+lo).intern());
    }
}
class Other { static String hello = "Hello"; }
1
2
package other;
public class Other { public static String hello = "Hello"; }

运行结果是:

1
true true true true false true
  • 同类、同包的string literals引用相同的String对象。
  • 不同类、同包的string literals指向相同的String对象。
  • 不同类、不同包的string literals指向相同的String对象。
  • 由constant expression计算得到的字符串是在编译期被计算出来的,被视同为string literal处理。
  • 在运行期通过串接计算得到的字符串则是新创建的,所以不是同一个对象。
  • 显式得intern一个计算得到的字符串的结果,和已经存在的具有相同内容的string literal一样。

参考资料

版权

评论