【String】关于intern方法的测试与理解

作者在学习虚拟机时研究intern知识,通过代码案例分析其执行结果。在jdk 1.7以上环境,分析了案例1和案例2不同执行顺序下输出结果不同的原因,是由于intern执行顺序影响。还通过方法测试验证intern在字符串非首次出现时的情况。

最近在看虚拟机,了解到了有关intern的知识,感觉理解起来有点困难,于是乎就直接动手敲敲代码。

以下是案例(注意:测试环境是jdk 1.7以上,1.6以下结果因为永久代的影响又是另一个!)

案例1:

String str1 = new String("计算机") + new String("软件");
        System.out.println(str1 == str1.intern());
        System.out.println(str1 == "计算机软件");

输出结果:true true

案例2:

    String str1 = new String("计算机") + new String("软件");
        System.out.println(str1 == "计算机软件");
        System.out.println(str1 == str1.intern());
      

输出结果:false false

Q:为什么两句输出语句交换了位置就输出了,不同的结果呢?

A:

首先肯定不是因为println交换位置而导致的,实际上是因为intern的执行顺序的不同影响的结果。

我们逐句分析,首先将new了两个String类型赋值给str1对象。

此时常量池里面存在了“计算机”,“软件”这两个字符串

假如先执行案例2

我们可以看到 str1的内存地址是@498指向一个char数组,str1与“计算机软件”的地址比较的时候肯定是不相同的,所以第一句返回的是false。

而因为比较的时候“计算机软件”这个字符串已经在字符串常量池中被创建,所以intern方法(jdk1.7中会先查询字符串常量池,若没有又会到堆中再去查询并存储堆的引用,然后返回。如果字符常量池中已经有该字符则无意义。),所以

str1与str1.intern()做比较就等于str1与“计算机软件”做比较。所以返回的也是false。

假如先执行案例1

执行intern方法,因为“计算机软件”是第一次出现,所以常量池中并没有这个字符串,所以会到堆中查询,并储存堆的引用,因为str1对象就是指向堆中储存“计算机软件”的对象,所以两者地址一样返回的是true,而同时字符串也会被复制到字符串常量池中,且引用为堆中的那个对象,所以当str1与“计算机软件”做比较时,返回的结果也是true。

 

为了验证intern在字符串并非第一次出现时是无意义的,我写了以下方法测试:

  String str1 = new String("计算机") + new String("软件");
        System.out.println(str1 == str1.intern());
        System.out.println(str1 == "计算机软件");


        String str2 = new String("计算机") + new String("软件");
        str2.intern();
        System.out.println(str2 == "计算机软件");
        System.out.println(str1 == "计算机软件");

输出结果为

true
true
false
true
如果我的理解有错,麻烦各位大牛一定要在评论区指正,谢谢~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值