使用String.intern()可以保证内容相同的字符串变量引用同一个内存对象。基本类型常量池常量池类似于JAVA系统级别提供的缓存,基本类型对应的缓冲池如下:boolean值true和false所有byte值short值在-128之间而127int值在-128和127char之间,范围在\u0000到\u007F之间,创建时并不总是使用常量池,比如newInteger(123)和Integer.valueOf(123)newInteger(123)会创建一个每次都有新对象。Integer.valueOf(123)将使用缓存池中的对象。多次调用将获得同一个对象的引用。String常量池主要有两种使用方式:直接用双引号声明的String对象会直接存储在常量池中。如果不是用双引号声明的String对象,可以使用String提供的intern方法。intern方法会从字符串常量池中查询当前字符串是否存在。如果不存在,则将当前字符串放入常量池。接下来主要讲String#intern方法。String#intern方法是一种本机方法。如果常量池中存在当前字符串,则直接返回当前字符串。如果常量池中没有该字符串,则将该字符串放入常量池并返回。查看你的jdk源码,可以发现它的大致实现结构是:JAVA使用jni调用C++实现的StringTable的intern方法。StringTable的intern方法类似于Java中HashMap的实现,但是不能自动扩容。默认大小为1009,需要注意的是,String的StringPool是一个固定大小的Hashtable,默认大小和长度都是1009,如果放入StringPool的String过多,会导致严重的Hash冲突,导致链表很长,链表很长。直接的影响是调用String.intern时,性能会明显下降(因为需要一个一个的找)。例子Strings=newString("abc")这条语句创建了2个对象,第一个对象是常量池中存放的"abc"字符串,第二个对象是JAVAHeap中的String对象publicstaticvoidmain(String[]args){Strings=newString("1");实习生();字符串s2="1";System.out.println(s==s2);字符串s3=新字符串("1")+新字符串("1");s3.实习生();字符串s4="11";System.out.println(s3==s4);}jdk6下打印结果为falsefalsejdk7下为truepublicstaticvoidmain(String[]args){Strings=newString("1");字符串s2="1";实习生();System.out.println(s==s2);Strings3=newString("1")+newString("1");Strings4="11";s3.实习生();System.out.println(s3==s4);}打印结果为:jdk6falsefalsejdk7falsefalsejdk7这个版本对intern操作和常量池做了一些改动。主要包括2点:String常量池从Perm区移到JavaHeap区。在使用String#intern方法时,如果堆中有对象,会直接保存对象的引用,而不用重新创建对象。参考文本:深入剖析String#intern
