First Blood
先看下面的代码:
String s = new String("1"); String s1 = s.intern(); System.out.println(s == s1);
打印结果为: false
对于 new String("1")
,会生成两个对象,一个是String类型对象,它将存储在 Java Heap 中,另一个是字符串常量对象"1",它将存储在 字符串常量池 中。 s.intern()
方法首先会去字符串常量池中查找是否存在字符串常量对象"1",如果存在则返回该对象的地址,如果不存在则在字符串常量池中生成为一个"1"字符串常量对象,并返回该对象的地址。 如下图: 变量 s
指向的是Stirng类型对象,变量 s1
指向的是"1"字符串常量对象,所以 s == s1
结果为false。
Double kill
在上面的基础上我们再定义一个s2如下:
String s = new String("1"); String s1 = s.intern(); String s2 = "1"; System.out.println(s == s1); System.out.println(s1 == s2); // true
s1 == s2
为true,表示变量s2是直接指向的字符串常量,如下图:
Triple kill
在上面的基础上我们再定义一个t如下:
String s = new String("1"); String t = new String("1"); String s1 = s.intern(); String s2 = "1"; System.out.println(s == s1); System.out.println(s1 == s2); System.out.println(s == t); // false System.out.println(s.intern() == t.intern()); // true
s == t
为false,这个很明显,变量s和变量t指向的是不同的两个String类型的对象。 s.intern() == t.intern()
为true,因为intern方法返回的是字符串常量池中的同一个"1"对象,所以为true。
Ultra kill
在上面的基础上我们再定义一个x和s3如下:
String s = new String("1"); String t = new String("1"); String x = new String("1") + new String("1"); String s1 = s.intern(); String s2 = "1"; String s3 = "11"; System.out.println(s == s1); System.out.println(s1 == s2); System.out.println(s == t); System.out.println(s.intern() == t.intern()); System.out.println(x == s3); // fasle System.out.println(x.intern() == s3.intern()); // true
变量x为两个String类型的对象相加,因为 x != s3
,所以x肯定不是指向的字符串常量,实际上x就是一个String类型的对象,调用 x.intern()
方法将返回"11"对应的字符串常量,所以 x.intern() == s3.intern()
为true。
Rampage
将上面的代码简化并添加几个变量如下:
String x = new String("1") + new String("1"); String x1 = new String("1") + "1"; String x2 = "1" + "1"; String s3 = "11"; System.out.println(x == s3); // false System.out.println(x1 == s3); // false System.out.println(x2 == s3); // true
x == s3
为false表示x指向String类型对象,s3指向字符串常量; x1 == s3
为false表示x1指向String类型对象,s3指向字符串常量; x2 == s3
为true表示x2指向字符串常量,s3指向字符串常量;
所以我们可以看到 new String("1") + "1"
返回的String类型的对象。
总结
现在我们知道intern方法就是将字符串保存到常量池中,在保存字符串到常量池的过程中会先查看常量池中是否已经存在相等的字符串,如果存在则直接使用该字符串。 所以我们在写业务代码的时候,应该尽量使用字符串常量池中的字符串,比如使用 String s = "1";
比使用 new String("1");
更节省内存。我们也可以使用 String s = 一个String类型的对象.intern();
方法来间接的使用字符串常量,这种做法通常用在你接收到一个String类型的对象而又想节省内存的情况下,当然你完全可以String s = 一个String类型的对象;但是这么用可能会因为变量s的引用而影响String类型对象的垃圾回收。所以我们可以使用intern方法进行优化,但是需要注意的是 intern
能节省内存,但是会影响运行速度,因为该方法需要去常量池中查询是否存在某字符串。
如果觉得这篇文章能让你学到知识,能否帮忙 转发 ,将知识 分享 出去。 如果想第一时间学习更多的精彩的内容,请 关注 微信公众号: 1点25
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
高性能网站建设进阶指南
Steve Souders / 口碑网前端团队 / 电子工业出版社 / 2010年4月 / 49.80元
性能是任何一个网站成功的关键,然而,如今日益丰富的内容和大量使用Ajax的Web应用程序已迫使浏览器达到其处理能力的极限。Steve Souders是Google Web性能布道者和前Yahoo!首席性能工程师,他在本书中提供了宝贵的技术来帮助你优化网站性能。 Souders的上一本畅销书《高性能网站建设指南》(High Performance Web Sites)震惊了Web开发界,它揭示......一起来看看 《高性能网站建设进阶指南》 这本书的介绍吧!