最主要的好处就是安全,因为知晓这个对象不可能会被修改,在多线程环境下也是线程安全的(你想想看,你引用的对象是一个不可变的值,那么谁都无法修改它,那它永远就是不变的,别的线程也休息动它分毫,你可以放心大胆的用) 。
然后,配合常量池可以节省内存空间,且获取效率也更高(如果常量池里面已经有这个字符串对象了,就不需要新建,直接返回即可) 。
所以这里就提到 字符串常量池了 。
例如执行了 String yesA = "a" 这行代码,我们现在知道 yesA 是一个引用指向了堆中的对象 a,再具体点其实指向的是堆里面的字符串常量池里的对象 a 。
如果字符串常量池已经有了 a,那么直接返回其引用,如果没有 a,则会创建 a 对象,然后返回其引用 。
这种叫以字面量的形式创建字符串 。
还有一种是直接 new String,例如:
String yesA = new String("a")
这种方式又不太一样,首先这里出现了字面量 “a”,所以会判断字符串常量池里面是否有 a,如果没有 a 则创建一个 a,然后会在堆内存里面创建一个对象 a,返回堆内存对象 a 的引用,也就是说返回的不是字符串常量池里面的 a
我们从下面的实验就能验证上面的说法,用字面量创建返回的引用都是一样的,new String 则不一样
文章插图
至此,你应该已经清晰字面量创建字符串和new String创建字符串的区别了 。
讲到这,经常还会伴随一个面试题,也就是 intern以下代码你觉得输出的值各是啥呢?你可以先思考一下
String yesA = "aaabbb";String yesB = new String("aaa") + new String("bbb");String yesC = yesB.intern();System.out.println(yesA == yesB);System.out.println(yesA == yesC);
好了,公布答案:文章插图
第一个输出是 false 应该没什么疑义,一个是字符串常量的引用,一个是堆内的(实际上还是有门道的,看下面) 。
第二个输出是 true 主要是因为这个 intern 方法 。
intern 方法的作用是,判断下 yesB 引用指向的值在字符串常量里面是否有,如果没有就在字符串常量池里面新建一个 aaabbb 对象,返回其引用,如果有则直接返回引用 。
在我们的例子里,首先通过字面量定义了 yesA ,因此当定义 yesC 的时候,字符串常量池里面已经有 aaabbb 对象(用equals()方法确定是否有对象),所以直接返回常量池里面的引用,因此 yesA == yesC
你以为这样就结束了吗?我们把上面代码的顺序换一下:
String yesB = new String("aaa") + new String("bbb");String yesC = yesB.intern();String yesA = "aaabbb"; // 这里换了System.out.println(yesA == yesB);System.out.println(yesA == yesC);
把 yesA 的定义放到 yesC 之后,结果就变了:文章插图
是不是有点懵?奇了怪了,按照上面的逻辑不应该啊 。
实际上,我最初画字符串常量池的时候,就将其画在堆内,也一直说字符串常量池在堆内,这是因为我是站在 JDK 1.8 的角度来说事儿的 。
在 JDK 1.6 的时候字符串常量池是放在永久代的,而 JDK 1.7 及之后就移到了堆中 。
文章插图
这区域的改变就导致了 intern 的返回值有变化了 。
在这个认知前提下,我们再来看修改顺序后的代码具体是如何执行的:
1.String yesB = new String("aaa") + new String("bbb");此时,堆内会新建一个 aaabbb 对象(对于 aaa 和 bbb 的对象讨论忽略),字符串常量池里不会创建,因为并没有出现 aaabbb 这个字面量 。
2.String yesC = yesB.intern();此时,会在字符串常量池内部创建 aaabbb 对象?
关键点来了 。
在 JDK 1.6 时,字符串常量池是放置在永久代的,所以必须新建一个对象放在常量池中 。
但 JDK 1.7 之后字符串常量池是放在堆内的,而堆里已经有了刚才 new 过的 aaabbb 对象,所以没必要浪费资源,不用再存储一份对象,直接存储堆中的引用即可,所以 yesC 这个常量存储的引用和 yesB 一样 。
3.String yesA = "aaabbb";同理,在 1.7 中 yesA 得到的引用与 yesC 和 yesB 一致,都指向堆内的 aaabbb 对象 。
推荐阅读
- 传染性红斑
- 红茶也要喝新茶吗,红茶女性喝了功效与作用吗
- 大学|实在抱歉,211研究生我们见多了,你的本科是211学历吗?
- 你对海南的酒文化了解多少
- |四人五一钓鱼被抓,工作估计黄了,这种钓鱼行为可判刑
- 滇红茶功效与作用,凤庆滇红茶时间放长了好喝吗
- 职业教育|这里是职场,别抖机灵了
- 补水|解锁夏季不脱妆新方法,14小时持久带妆轻松拿捏住了
- 化妆|女人上了年纪,化妆只要认准“3个地方”就行,不扮嫩也有好气色
- 显卡|RTX 40系显卡来了!性能翻倍:价格/功耗感人