public static void main(String[] args) { String s1 = new String("1"); s1.intern(); String s2 = "1"; System.out.println(s == s2); String s3 = new String("1") + new String("1"); s3.intern(); String s4 = "11"; System.out.println(s3 == s4); }
jdk1.6 intern()方法会把首次遇到的字符串实例复制到永久代的字符串常量池中存储,返回的也是永久代的字符串引用。
检查字符串池里是否存在xxxx这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会把xxxx添加到字符串池中,然后再返回它的引用
补充小点
value[]
的值,就指向常量池中的对象,如果没有,就在常量池中新建一个字符串对象,然后再指向它,而String对象本身是在堆里的public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
"hello"这个字符串,在创建对象之前,就在常量池中已经存在了:
(1)那么第一行代码String a = "hello";就是在常量池中创建了值为"hello"的对象,我们讨论的是第二行代码。
(1)在第二行代码String b = new String("hello");是在堆里面创建了一个对象,引用b指向这个对象,而常量池中有值为"hello"这个对象,然后引用b指向的对象(new String("hello"))的成员变量char数组value[]指向常量池值为"hello"这个对象就行了,它就创建了一个对象new String("hello")
https://blog.csdn.net/fenger3790/article/details/105247924/
jdk1.7 intern()方法返回在
因为 jdk6中的常量池是放在 Perm 区中的,Perm区和正常的 JAVA Heap 区域是完全分开的。上面说过如果是使用引号声明的字符串都是会直接在字符串常量池中生成,而 new 出来的 String 对象是放在 JAVA Heap 区域。intern
在 Jdk6 以及以前的版本中,字符串的常量池是放在堆的Perm区的,Perm区是一个类静态的区域,主要存储一些加载类的信息,常量池,方法片段等内容,默认大小只有4m,一旦常量池中大量使用 intern 是会直接产生java.lang.OutOfMemoryError:PermGen space
错误的。在 jdk7 的版本中,字符串常量池已经从Perm区移到正常的Java Heap区域了。为什么要移动,Perm 区域太小是一个主要原因,当然据消息称jdk8已经直接取消了Perm区域,而新建立了一个元区域。应该是jdk开发者认为Perm区域已经不适合现在 JAVA 的发展了。
在jdk1.6中,该方法把字符串的值复制到常量区,然后返回常量区里这个字符串的值;
在jdk1.7里,该方法在常量区记录该字符串首次出现的实例引用,然后返回该地址,常量区可以保存字面量也可以保存字符串对象在堆中的引用。
原文:https://www.cnblogs.com/zdcsmart/p/12674330.html