String.intern() 去字符串常量池里找有没有一份一样的内容:
- 有:返回池里那一份
- 没有:JDK 7 起在池里放一个指向堆上这个对象的引用,再返回它(JDK 6 则是在池里再拷一份)
java
String a = new String("abc");
String b = new String("abc");
System.out.println(a.intern() == b.intern()); // true
System.out.println(a.intern() == b); // false
System.out.println(a.intern() == a); // falsenew String("abc") 第一次会在池里留下字面量 "abc",堆上再有一个对象。a、b 是两个堆对象,所以 intern() 得到的是池里那份,和 a、b 本身都不是同一个引用。
字面量 "abc" 本身就在池里,所以:
java
String s = "abc";
System.out.println(s.intern() == s); // true拼接出来、编译期看不出字面量的,池里事先可能没有:
java
String s3 = new String("1") + new String("1");
s3.intern();这时 intern 的行为更依赖 JDK 版本。日常比较字符串内容用 equals,不要靠 intern() 和 == 赌池子。intern 适合需要把大量重复字符串收敛成同一份引用的场合,用之前要清楚池是 JVM 全局的。