1.String创建对象的方式
String a ="123";
如果常量池中有这个字面值的话,直接将a指向常量池中的这个值;否则,创建一个123,并将a指向他
String a =new ("123");
如果常量池中有这个对象的话,则在堆中也会创建一个对象;如果常量池中没有的话,在推中创建出这个对象的同时,在池中也会添加这样一个字面值。
2.String的intern方法
// jdk1.6 // false、true、false、true、false、true // jdk1.7 // false、true、true、true、false、true // jdk1.8 // false、true、true、true、false、true String str1 = new StringBuffer("ja").append("va").toString(); String intern1 = str1.intern(); System.out.println(intern1 == str1); System.out.println(intern1.equals(str1)); String str2 = new StringBuffer("我是").append("中国人").toString(); String intern2 = str2.intern(); System.out.println(intern2 == str2); System.out.println(intern2.equals(str2)); String str3 = new StringBuffer("我是").append("中国人").toString(); String intern3 = str3.intern(); System.out.println(intern3 == str3); System.out.println(intern3.equals(str3)); /** * "java"字符串常量比较特殊,它是固定存在字符串常量池中,所以都是返回了false * Java6中字符串常量池是在永久代区,intern方法会将首次遇到的字符串复制到那里,返回的也是永久代中这个字符串的引用。不建议使用这个方法。 * Java7中字符串常量池被放到了堆中,intern的实现也不再是复制实例,只是在常量池中记录首次出现的实例引用。 * Java8同7一致 */
代码解释:
(1)java1.6
str1、str2和str3都是指向堆内存的地址;
intern1、intern2和intern3都是指向永生代的常量池地址;
所以,“==”的地址比较肯定都是false,但是equals比较的都是内容,所以都是true;
(2)java1.7
str1、str2和str3都是指向堆内存的地址
由于“java”字符串的特殊性,intern1指向的常量池的地址,所以第一个地址的比较就是false;
intern2和str2都是指向同一块堆地址,所以第二个地址的比较就是true;
由于str3的字符串已经在常量池中存在,所以intern3就和intern2、str2的地址保持一致;
3.intern方法的作用
在String对象维持的一个私有池里面存放的字符串“123456789123456789123456789”可能只有一个,因为每次比对都是一样,所以是不会将这样的对象重复放到池里面的,所以调用intern()方法就是完成的这个功能,其返回的只是里面的同一个字符串,而没有创建新的字符串,所以不会占用太多的空间