概念:

String.intern()是一个native方法,它的作用是:如果字符串常量池中已经包含了一个等于此String对象的字符串,则返回代表池中这个字符串的String对象;否则,将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。

上述的黑体部分,在jdk1.6和1.7(含以上)中的表现形式是不同的。

1.jdk1.6中,字符串常量池是放在于永久代中的,这个是完全区分于堆内存的。intern()方法会把首次遇到的字符串实例复制一个到永久代中,返回的也是永久代中这个字符串实例的引用。

2.jdk1.7中,字符串常量池已经被放在了堆中,而intern()方法不会在复制实力,只是在常量池中记录首次出现的实例引用,因此对堆内存中的String引用使用intern()方法,常量池中并不会出现对应的字符串,而是指向了堆内存中的实例。

代码分析:

public class Test4 {

    public static void t1(){
        //实例s1存在于堆内存中,常量池中并不存在该字符串“java”
        String s1 = new StringBuilder("mjp").append("cmm").toString();
        //s1 intern会检查常量池是否有“mjpcmm”,这里不存在,所以直接在常量池中记录该引用,即s2指向了s1,所以s1==s2返回true
        String s2 = s1.intern();
        System.out.println(s1 == s2);//这里打印出true
    }

    public static void t2(){
        //先再字符串常量池中创建了mjpcmm这个常量,s保存对应常量池的引用地址
        String s = "mjpcmm";
        //实例s1存在于堆内存中,所以这里有两个引用,s指向常量池,s1则指向堆内存
        String s1 = new StringBuilder("mjp").append("cmm").toString();
        //s1 intern会检查常量池是否有“mjpcmm”,这里已经存在,所以直接返回该引用,即s2指向了s,所以s==s2返回true,s1==s2返回false
        String s2 = s1.intern();
        System.out.println(s == s2);//这里打印出true
        System.out.println(s1 == s2);//这里打印出false
    }

    public static void main(String[] args) {
//        t1();
        t2();
    }

}

欢迎加入学习交流群569772982,大家一起学习交流。


java部落
90 声望13 粉丝