一、String 变量创建分析
(1) 在HotSpot VM里实现的string pool功能的是一个StringTable类,它是一个Hash表,默认值大小长度是1009;这个StringTable在每个HotSpot VM的实例只有一份,被所有的类共享。字符串常量由一个一个字符组成,放在了StringTable上。
(2) 在JDK6.0中,StringTable的长度是固定的,长度就是1009,因此如果放入String Pool中的String非常多,就会造成hash冲突,导致链表过长,当调用String#intern()时会需要到链表上一个一个找,从而导致性能大幅度下降;
(3) 在JDK7.0中,StringTable的长度可以通过参数指定 -XX:StringTableSize=xxxxxx
String lily = "Lily";
String tomsy = "tom" + "sy";
直接赋值,则为常量,在编译期间就已经确定,直接存储在字符串常量池中,对于 tomsy jvm做了优化不会创建tom 、sy 只会创建tomsy在常量池中,此时lily.intern() 就是一个常量
String lyli_1 = new String("Lily");
String tomsy = new String("tom") + new String("sy");
创建对象,变量的值在程序运行期间确定。首先lily_1会在字符串常量池查找是否有没有创建Lily,然后在堆上创建一个String对象实例 lily_1指向该实例。同理tomsy 也会在字符串常量池查找或创建tom、sy两个常量,同时在堆上创建两个String对象以及合成后的tomsy三个对象。
tomsy.intern();
String tomsy_1 = "tomsy";
此时在执行intern()方法,先查找字符串常量池中是否已存在,如果不存在则会在常量池添加一份tomsy对象的引用,返回该引用,此时tomsy_1赋值的时候则会直接把该引用返回给tomsy_1
System.out.println(tomsy == tomsy_1); 返回true
String mess = "abc";
String mess1 = new String("abc");
String a = mess.intern();
String b = new String("abc").intern();
mess == a true
mess == mess1 false
a == b true
intern() 首先会检测 字符串常量池中是否有此字符串 有则直接返回 引用,否则新建返回改引用,
new String("abc") 在堆中创建对象 同时 会检测 字符串常量池中是否有改字符串 无则新建 有则什么也不做 返回的是 堆中的对象的引用