这时候玩一下池化 intrern():
加上实例看看 == 看看内存地址是不是一样:
String name1 = "JC"; String name = "JCccc"; String nameNew = new String(name1 + "ccc"); nameNew = nameNew.intern(); System.out.println(name == nameNew);
结果是 true (因为池化,nameNew 放弃了 堆的照顾,指向了字符串常量池)
这里又有个好玩的点,
就是 池化方法 intern() 的玩法,不是说调了 intern() 就 会把原先指向堆的直接指到字符串常量池。
是调了 intern() 而且 再去接收 intern() 返回的对象引用,这时候才真的会让 nameNew改变引用。
结合代码玩玩:
String name1 = "JC"; String name = "JCccc"; String nameNew = new String(name1 + "ccc"); nameNew.intern(); System.out.println(name == nameNew); nameNew = nameNew.intern(); System.out.println(name == nameNew);
运行结果:
可以看到池化方法调用但是没有接收的时候,依然是 false ;
在池化方法调用 并接收返回,这时候nameNew才真正改变引用指向字符串常量池里的“JCccc”.
最后再放个代码例子:
//字符串常量池中的对象 String a = "JC"; //字符串常量池中的对象 String b = "ccc"; //字符串常量池中的对象 String str1 = "JC" + "ccc"; //在堆上创建的新的对象 String str2 = a + b; //常量池中的对象 String str3 = "JCccc"; System.out.println(str1 == str2);//false 字符串常量池 的 跟 堆的 比较 System.out.println(str1 == str3);//true 字符串常量池 的 跟 字符串常量池 比较 System.out.println(str2 == str3);//false 字符串常量池 的 跟 堆的 比较 str2.intern(); System.out.println(str1 == str2);//false str2池化不接收 System.out.println(str2 == str3);//false str2池化不接收 str2=str2.intern(); System.out.println(str1 == str2);//true str2池化且接收 System.out.println(str2 == str3);//true str2池化且接收
认真看完上面我啰嗦的这些内容,
后面这些常见的 ‘这里一共创建了几个String对象 ’ 题 , 随手拿捏。
开始整一些好玩的,也就是经常被问到的面试题:
例题1 :
这里创建了几个对象?
String name = "JCccc"; System.out.println(name);
答:
String对象一个
char[]数据一个
所以是 1个 。
咱们debug,眼看为实:
例题2:
这里创建了几个对象?
String s1 = new String("JCccc"); System.out.println();
答:
1个是字面量创建的对象,丢到了字符串常量池里面了;
1个是new String 在堆里面创建的对象。
所以是 2个。
例题3:
这里创建了几个对象?
String s = "JCccc"; String s1 = new String("JCccc"); System.out.println();
答:
也是 2个 。
1个是字面量创建的对象,丢到了字符串常量池里面了;
1个是new String 在堆里面创建的对象。
同样,debug眼见为实:
再往下走一行,看到 String s1 = new String("JCccc"); 被执行了,只加了个 String对象 :
加大难度
例题4:
这里创建了几个对象?
String s = "JCccc"; String a="JC"; String s1 = new String(a+"ccc"); System.out.println();
答:
5个
3个
再加上 new String 和 触发StringBuilder创建 这两个
3+2 =5
也许,很多人有疑惑,就是说即使看了了编译出来的字节码, 还是不相信 因为 + 符合 触发的 StringBuilder导致 会创建一个 String 对象。
那么我们还是眼见为实,一探到底,看一下StringBuilder的toString 源码,里面还是new了一哈:
嗯 ,这篇就到这吧。