了解Java中String类中的intern()方法

String类中的intern()方法是手动把String对象加入到字符串常量池中
先来看一个简单的代码:

示例1:

  @Test
    public void test1(){//测试通过
        String str1 = new String("hello").intern() ;
        String str2 = "hello" ;
        Assert.assertTrue(str1 == str2);
    }

第一句:首先在堆中创建对象"hello",也会在常量池中创建"hello",intern()方法则检查常量池中 是否含有"hello",结果发现常量池中含有,则返回常量池中"hello"的地址
第二句:指向常量池中"hello"对象
结果:str1指向常量池中的“hello”对象,str2指向常量池中的“hello”对象

实例二

 @Test
    public void test2(){//测试不通过
        String s1 = new String ("hello");
        String s2 = s1.intern();
        Assert.assertTrue(s1==s2);
    }

第一句:堆中创建了"hello",也会在常量池创建"hello"
第二句:intern()会去常量池检查是否存在"hello",结果发现存在,则此时返回常量池的引用地址给s2
第三句:此时s1指向堆中"hello",s2指向常量池"hello"

示例三

  @Test
    public void test3(){ //测试不通过
        String s1 = new String("hel") + new String("lo");
        String s2 = "hello";
        s1.intern();
        Assert.assertTrue(s1==s2);
    }
    

第一句:在堆中创建了三个对象,分别是"hello",“lo”,拼接之后产生"hello",也会在常量池中创建"hel",“lo”
第二句:在常量池中创建"hello",此时常量池中含有"hel",“lo”,“hello”
第三句:检查常量池是否有"hello",结果发现有了,此时应该返回常量池"hello"的地址,但是并没有变量去接收这个返回值,所以在这里这一句没什么用
第四句:s1指向堆中"hello",S2指向常量池"hello"

示例四


    @Test
    public void test4(){//测试通过
        String s1 = new String("hel") + new String("lo");
        s1.intern();
        String s2 = "hello";
        Assert.assertTrue(s1==s2);
    }

第一句:在堆中创建了三个对象,分别是"hello",“lo”,拼接之后产生"hello",也会在常量池中创建"hel",“lo”
第二句:检查到"hello"不在常量池中,如果在jdk1.6就将"hello"添加到常量池中,如果是jdk1.7,则在常量池中保存堆中对象的引用,也就是地址
第三句:检查到常量池有一个地址保存了"hello"对象的引用,则s2就直接指向"hello"这个字符串地址,也就是是堆中的"hello"
第四句:s1指向堆中的“hello”,s2指向堆中“hello”

实例5

  @Test
    public void test3(){//测试通过
        String s1 = new String("hel") + new String("lo");
        String s2 = "hello";
        Assert.assertTrue(s2==s1.intern());
    }

第一句:在堆中创建了三个对象,分别是"hello",“lo”,拼接之后产生"hello",也会在常量池中创建"hel",“lo”
第二句:创建常量池中的对象“hello”
第三句:检查常量池中是否有“hello”这个对象,结果发现有了,则返回常量池中的对象引用
结果:s3指向常量池中的对象,s1指向常量池中的对象

在jdk1.6及以下版本和jdk1.7及以上版本
对intern方法调用会存在差异,在jdk1.6中,,如果字符串常量池先前已创建出该字符串对象,则返回池中的该字符串的引用。否则,将此字符串实例复制到字符串常量池中,并且返回该字符串的引用
但是在jdk1.7中,当调用intern()方法时,如果字符串常量池先前已创建出该字符串对象,则返回池中的该字符串的引用,只是会把字符串实例的引用添加到常量池中,并返回此引用;

猜你喜欢

转载自blog.csdn.net/qq_44723296/article/details/106210818
今日推荐