返回信息流根据《深入理解java虚拟机》
JDK 1.7后,intern 方法会先去查询常量池中是否有已经存在,如果存在,则返回常量池中的引用,这一点与之前没有区别。
区别在于,如果在常量池找不到对应的字符串,则不会再将字符串拷贝到常量池,而只是在常量池中生成一个对原字符串的引用。
简单的说,就是往常量池放的东西变了:原来在常量池中找不到时,复制一个副本放到常量池,1.7后则是将在堆上的地址引用复制到常量池。
那么下面这段代码:
1. 对于 s 和 s2,s.intern() 时发现 “1” 不在字符串常量池内,会把堆的引用保存到字符串常量中,那么当 String s2 = "1" 的时候,常量池中存在“1” 的引用地址,s2应该直接拿到指向s堆对象的引用,这时候判断,s==s2 应该是true ?
2. 对于s3和s4, 根据上面的说法s4拿到s3堆空间的引用所以返回true没问题
综上:为啥返回的不一样,第一个不应该是true吗?如果第一个是false,为啥第二个就是true了?
求指教,谢谢!
```java
//jdk1.8
String s = new String("1");
s.intern();
String s2 = "1";
System.out.println(s == s2); //false
String s3 = new String("1") + new String("1");
s3.intern();
String s4 = "11";
System.out.println(s3 == s4); //true
```
这是一条镜像帖。来源:北邮人论坛 / java / #64263同步于 2020/8/19
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
不懂就问:String 和 intern()
crazyalltnt
2020/8/19镜像同步16 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
所以关键是第二段的"+"对吗?这一句在编译是不做运算,所以常量池没有放入11而前面的s在编译时就在常量池放入了1。[ema11]
【 在 Lykr (Lykr) 的大作中提到: 】
: https://www.cnblogs.com/gxyandwmm/p/9495923.html 讲的很清楚了
第一个new String("1")是先后在常量区和堆上创建”1“和对象,s.intern时候 发现常量区已经有了”1“所以就不动了;
第二个 s3一开始指向的是堆中的11,但执行 intern 后,在常量区中增加了对堆中”11“的引用,定义s4是指向了该引用和s3是同一个对象,所以是true
楼上正解
【 在 itachiwwg (阿呆) 的大作中提到: 】
: 第一个new String("1")是先后在常量区和堆上创建”1“和对象,s.intern时候 发现常量区已经有了”1“所以就不动了;
: 第二个 s3一开始指向的是堆中的11,但执行 intern 后,在常量区中增加了对堆中”11“的引用,定义s4是指向了该引用和s3是同一个对象,所以是true
https://tech.meituan.com/2014/03/06/in-depth-understanding-string-intern.html
看完这篇就懂了
对对,过程我明白了。原理方面是我在4楼说的那个吗?
就是为何s创建时常量和堆都有1而s3只有堆中有1而常量池没有。
String s3 = new String("1") + new String("1");
+是stringbuilder实现的所以在执行之前,编译后加载的时候11没有放进常量池,1被放进常量池。而String s = new String("1");在编译后加载的时候就被放进常量池?
我的理解对吗?谢谢啦!
【 在 itachiwwg (阿呆) 的大作中提到: 】
: 第一个new String("1")是先后在常量区和堆上创建”1“和对象,s.intern时候 发现常量区已经有了”1“所以就不动了;
: 第二个 s3一开始指向的是堆中的11,但执行 intern 后,在常量区中增加了对堆中”11“的引用,定义s4是指向了该引用和s3是同一个对象,所以是true
嗯嗯,谢谢!看来主要区别原因就在于+号实现和执行,执行前,编译和加载时11没有在常量池被创建,只创建了直接new的1。
【 在 S12344 (Woo) 的大作中提到: 】
: https://tech.meituan.com/2014/03/06/in-depth-understanding-string-intern.html
: 看完这篇就懂了