真正理解String#intern

真正理解String#intern

intern作用

intern用来返回常量池中的某字符串,如果常量池中已经存在该字符串,则直接返回常量池中该对象的引用。
如果在常量池找不到对应的字符串,则不会再将字符串拷贝到常量池,而只是在常量池中生成一个对原字符串的引用。

案例分析

请先看字符串常量池,不然真的理解不透彻
jdk1.8测试:

案例一:

public static void main(String[] args) {
		//先在常量池放入1,再在堆上生成String obj,obj的char[] value指向常量池的1,栈上s1指向String obj
        String s1 = new String("1");
        //1已经在常量池了,所以这行代码没有任何意义
        s1.intern();
        //栈s2指向常量池的1
        String s2 = "1";
        //s1指向String obj, s2指向常量池,肯定不相等
        System.out.println(s1 == s2);//flase
		
		//用StringBuilder append 1和2,会把1和2放入到常量池中,堆中生成一个StringObj, obj的char[]value=12
		//注意此时常量池没有12,value不是指向常量池了,而是把12存在自己的内存中,栈s3指向obj
        String s3 = new String("1") + new String("2");
        //此时常量池没有12,他会把12的引用即String obj的引用放到常量池中(1.7以前是直接放12到常量池)
        s3.intern();
        //常量池有指向12的引用,把这个引用(即obj的地址)给s4
        String s4 = "12";
        //s3和s4都指向obj,所以相等
        System.out.println(s3 == s4);//true
    }

在这里插入图片描述

案例二:

 public static void main(String[] args) {
        String s1 = "hello";//栈s1指向常量池hello
        String s2 = " world";//栈s2指向常量池 world
        String s3 = s1+s2;//StringBuilder append hello和world,s3指向堆的obj,obj的char[]value存hello world
		//此时常量池没有hello world,把s3的引用存入常量池
        s3.intern();//这行代码如果移下一行结果就变了
        //s4指向常量池s3的地址
        String s4 = "hello world";
        System.out.println(s4 == s3);//true
    }

试着自己画一下图吧

案例三:

 public static void main(String[] args) {
 	  //toString里面new String(char []value)
 	  //往常量池添加计算机,软件这两个字符串
 	  //堆中String obj的char[]value保存计算机软件这个字符串,str1指向堆中obj
      String str1 = new StringBuilder("计算机").append("软件").toString();
      //因为此时常量池没有计算机软件,str1.intern()会把str1的引用添加到常量池并返回str1的引用,所以相等
      System.out.println(str1.intern()==str1);//输出true
	  
	  //往常量池添加ja,va这两个字符串
	  //因为常量池已经有java这个字符串了,堆中String obj的char[]value指向常量池的java,str2指向obj
      String str2 = new StringBuilder("ja").append("va").toString();
      //str2.intern()返回java,而str2指向堆obj,地址不相等
      System.out.println(str2.intern() == str2);//输出false
  }      

在这里插入图片描述

案例四:

 public static void main(String[] args) {
        String str1 = "a";//str1指向常量池a
        String str2 = "b";//str2指向常量池b
        String str3 = "ab";//str3指向常量池ab
        String str4 = str1 + str2;//str4指向堆String obj,obj的char[] value指向常量池ab
        String str5 = new String("ab");//str5指向堆String obj, obj的char[] value指向常量池ab

        System.out.println(str5 == str3);//f
        System.out.println(str5.intern() == str3);//t
        System.out.println(str5.intern() == str4);//f

        String a = new String("ab");//a指向堆String obj, obj的char[] value指向常量池ab
        String b = new String("ab");//b指向堆String obj, obj的char[] value指向常量池ab
        String c = "ab";//c指向常量池ab
        String d = "a" + "b";//d指向常量池ab (编译期确定)
        String e = "b";//e指向常量池b
        String f = "a" + e;//f指向堆String obj,obj的char[] value指向常量池ab (StringBuilder实现)

        System.out.println(b.intern() == a);//f
        System.out.println(b.intern() == c);//t
        System.out.println(b.intern() == d);//t
        System.out.println(b.intern() == f);//f
        System.out.println(b.intern() == a.intern());//t

    }

参考

美团

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值