String中的intern方法以及问题

一、首先我们要知道的事JDK1.6和JDK1.7中常量池的位置是不同的。
先来一波面试问:
面试问题:
(1)现在当有人问 String str = new String(“abc”);创建了几个对象,常量池有abc字段是1个,常量池没有"abc"字段则是2个。
(2)String str=“abc”;创建了几个对象(如果常量池里面已经有对象了就是0个。如果没有就是1个);
(3)new String(“abc”).intern();创建了几个对象(如果常量池里面已经有该字符串对象了就是1个,如果没有就是两个)

===============================华丽分隔符======================================

JDK1.7以上
(1) 当常量池中不存在"abc"这个字符串的引用,在堆内存中new一个新的String对象,将这个对象的引用加入常量池。(跟1.6的区别是常量池不再存放对象,只存放引用。)
(2) 当常量池中存在"abc"这个字符串的引用,str指向这个引用;

2.String str =new String(“abc”)
单纯的在堆内存中new一个String对象,通过StringBuilder 跟StringBuffer 构建的对象也是一样

3.intern方法 (1.7版本,返回常量池中该字符串的引用)
(1) 当常量池中不存在"abc"这个字符串的引用,将这个对象的引用加入常量池,返回这个对象的引用。
(2) 当常量池中存在"abc"这个字符串的引用,返回这个对象的引用;)
在这里插入图片描述
图1
在这里插入图片描述
图2
二、结论先了解
1、只在常量池上创建常量

String str= “QWQ”;

2、只在堆上创建对象

String str1 = new String("Q")+new String("WQ");

看过Java运行时数据区域的小伙子们,上面这两个结论肯定都知道了。不知道的小伙计,可以先了解下内存管理的区域哈。
接下来看下面两个结论:
3、在堆上创建对象,在常量池上创建常量

String str3 = new String("Q")+new String("WQ"); //只在堆上创建了对象
str3.intern(); //将QWQ对象的引用保存到常量池上【反复读几遍这句话哈,你会发现有不同】

4、在堆上创建对象,在常量池上创建引用,在常量池上创建常量【想啥呢,这种操作还可以,那坚决不行的,就是不可能这么干】

    String a1 = new String("Q") + new String("WQ");//只在堆上创建对象
    a1.intern();//在常量池上创建引用
    String a2 = "QWQ";//此时不会再在常量池上创建常量QWQ,而是将a1的引用返回给a2
    System.out.println(a1 == a2); //true

现在如果还是蒙的状况下,那就在看看下面的测试数据。

        String str1 = "计算机";
        String str2 = "计算机";
        System.out.println("str1==str2:" + (str1 == str2));
        
        String str3 = new String("计算机");
        System.out.println("str1==str3:" + (str1 == str3));
        System.out.println("str1==str3.intern():" + (str1 == str3.intern()));
        System.out.println("str2==str3.intern():" + (str2 == str3.intern()));
        
        String str4 = new String("计算机");
        System.out.println("str3==str4:" + (str3 == str4));
        System.out.println("str3.intern()==str4.intern():" + (str3.intern() == str4.intern()));


        String str5 = new StringBuilder("软件").append("工程").toString();
        System.out.println("str5.intern() == str5:" + (str5.intern() == str5));

        String str6 = new String(new StringBuilder("物联网").append("工程").toString());
        System.out.println("str6.intern() == str6:" + (str6.intern() == str6));

        String str7 = new String("物联网");
        System.out.println("str7.intern() == str7:" + (str7.intern() == str7));

JDK1.8的结果

str1==str2:true
str1==str3:false
str1==str3.intern():true
str2==str3.intern():true
str3==str4:false
str3.intern()==str4.intern():true
str5.intern() == str5:true
str6.intern() == str6:true
str7.intern() == str7:false

str7直接用new String(“物联网”)创建,"物联网"这字符串在一出现就自动创建成对象存放到常量池中,所以常量池里面存放的是"物联网"字符串的引用,并不是str7创建的对象的引用。

str5是通过StringBuilder构建的 在new StringBuilder(“软件”).append(“工程”).toString方法运行后,"软件工程"这个字符串对象才第一次出现。执行了intern方法后str5才被放到常量池中,此时str5跟str5.intern是同一个对象。

str6是作为对照组出现,这里为了确认StringBuilder 在toString方法执行后会不会把最终字符串放进常量池。很显然并没有,所以str6的intern才会跟str6是同一个对象。同时它也能验证出str7的new String()方式在初始化的时候就会把"物联网"字符串放进常量池中,同理我们可以得出在str5构建的时候常量池里面加入了"软件","工程"这两个字符串`

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值