很久前研究过这个问题,看深入理解jvm的时候有关于intern的讨论,当时是说intern方法在jdk6和jdk7之间会有不同。
常量池一般是类加载的时候确定了一些自定义的常量,比如s1="abc"。但是intern方法可以让方法在运行时也可以往常量池中添加常量。
intern方法大致理解为:
如果常量池中存在当前字符串, 就会直接返回当前字符串. 如果常量池中没有此字符串, 会将此字符串放入常量池中后, 再返回。
一般在jdk6和jdk7以后会有区别,是因为常量池在7以后被拿到堆中了。
String s=new String("123");
s.intern();
jdk7以后常量池是不是也可以放引用啊?比如上面这个代码,常量池中放的是"123"这个字符串还是s这个对象的引用?
@darknessplus: 我一般是这么简单理解的,
s是存在栈中的,s地址指向堆中,就是一个String对象实例,当然也包含它的对象数据实例"123"。
String s1 = s.intern();其实就是如果在常量池中有"123"则新建的s1对象直接指向这个"123",
如果常量池没有"123",则创建出来,新建的s1对象还是直接指向这个"123"。
@让我发会呆: 感谢!
https://blog.csdn.net/shanksqian/article/details/78330294 这个总结的也很好
这是个有意思的问题呀
String s1 = "Test";
String s2 = "Test";
String s3 = new String("Test");
final String s4 = s3.intern();
assertTrue(s1 == s4);
s1指向的是常量池,常量池是位于方法区的,区别于堆,你可以了解下jvm的内存,至于String的intern()方法返回的是规范化文本,简单说就是使用equals方法与常量池中的字符串比较,看看有没有相同的字符串,如果有直接返回常量池中的引用,如果没有,则在常量池添加一个跟自己一样的字符串并返回引用
常量区位于方法区?jdk1.7以后不是将常量区放在堆里了吗?同时常量区还可以保存字符串在堆里的引用,这是我看过一些博客上说的。
所以我的疑问是s1指向的是方法区中的常量区,还是堆中的常量区?
还有intern方法的过程是怎么样的?既然常量区中有字符串在堆中的引用,是不是每次对比还要区分是字面量还是引用?
@darknessplus: 我看的应该是jdk7之前的