一直对String对象里面的intern()方法不是很了解,最近在读《深入理解Java虚拟机》这本书里面终于得到了一个比较清晰的解释。这个方法是可以获得一个具体的String在字符串常量池中的一个引用,书里面有一段实例代码,

String str1= new StringBuilder("计算机").append("软件").toString();
System.out.println(str1.intern()==str1);

String str2=new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern()==str2);

在Java1.7上运行的结果是,

true
false

原因如书上所说的,“计算机软件”这个字符串是之前没有出现过的,所以String.intern()在首次遇到没出现过的字符串时会把其对应在堆上的引用存到字符串常量池中。

但是我对实例代码中为什么要用StringBuilder.append()方法有些疑问,所以加了如下代码,

String str= new StringBuilder("计算机软件").toString();
System.out.println(str.intern()==str);

String str1= new StringBuilder("计算机").append("软件").toString();
System.out.println(str1.intern()==str1);

String str2=new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern()==str2);

结果却变成了,

false
false
false

所以我猜测应该是jvm在加载类的时候就已经把代码中存在的字符串存在常量池中了。原来的例子也是出于这个考虑才用追加的方式来创建字符串,从而达到“首次出现”的目的。