intern方法深度解析
大家好,我是欧阳方超,公众号同名。
1 概述
Java中,String类是被频繁使用的类之一,而String.intern()方法更是一个独特且容易让人混淆的方法。这个方法在不同的Java版本有着不同的行为表现,博文就探讨它在Java6及以前版本与Java7及以后版本中的差异。
2 String.intern()方法
String.intern()方法的主要功能的检查字符串常量池中是否存在于当前字符串内容相同的字符串。如果存在,就返回常量池中该字符串的引用,如果不存在,处理方式会因Java版本而异。
2.1 Java 6及以前版本
在Java6及以前的版本中,字符串常量池位于方法区(永久代),和堆内存相互隔离。当调用intern()方法,且常量池中不存在对应字符串时,会在方法区的字符串常量池中复制一份字符串内容,创建一个新的字符串对象。
示例
public class InternExample {
public static void main(String[] args) {
String s1 = new String("1") + new String("1");
String s2 = s1.intern();
System.out.println(s1 == s2);
}
}
代码解释
String s1 = new String(“1”) + new String(“1”);在堆内存中创建了一个值为11的字符串对象,s3指向该对象。
s1.intern()由于常量池中没有11,会在方法区的字符串常量池中创建一个新的11对象,s2指向这个新对象。
s1==s2,由于s1指向堆内存中的对象,s2指向方法区的对象,因此结果为false。
2.2 Java7及以后版本
从Java7开始,字符串常量池被移到了堆内存中。当调用intern()方法,且常量池中不存在对应字符串时,会将堆中这个字符串对象的引用添加到字符串常量池中,而不是再复制一份新的字符串内容。
示例
public class InternExample {
public static void main(String[] args) {
String s1 = new String("1") + new String("1");
String s2 = s1.intern();
String s3 = "11";
System.out.println(s2 == s3);
}
}
代码解释
String s1 = new String(“1”) + new String(“1”);在堆内存中创建一个值为11的字符串对象,s1指向该对象。
s1.intern(),由于常量池中没有11,会把s1所指向的11对象的引用添加到字符串常量池中,并且把引用返回给s2。
String s3 = “11”;s3会直接指向常量池中已存在的引用所敌营的堆内存对象,也就是s1指向的对象,也是s2指向的对象。
s2==s3,由于s1、s2、s3指向同一个堆内存对象,因此输出为true。
3 总结
Java6及以前,intern()方法在常量池不存在对应字符串时,会在方法区复制新的字符串对象。
java7及以后,intern()方法在常量池不存在对应字符串时,会将堆中字符串对应的引用添加到常量池。
了解 String.intern() 方法在不同 Java 版本中的行为差异,有助于更好地理解字符串常量池的工作原理,避免在编程中因引用问题出现意外的结果。
我是欧阳方超,把事情做好了自然就有兴趣了,如果你喜欢我的文章,欢迎点赞、转发、评论加关注。我们下次见。