String的intern()

预备知识:

  • 对于jdk1.7以下的版本,常量池在方法区;对于jdk1.7及以上版本,常量池被放入到了堆空间中。
  • 对象在堆区,对象引用在栈区,对象引用存储的是对象所在地址(对象访问有句柄方式和直接指针方式两种)。
  • "=="用于判定两端的是否相等。偷偷对做一个定义:对于引用s来说,s的值表示s的内容所存放的地址

以下参考SEU_Calvin的文章

		String s = new String("1");//生成常量池中的“1” 和堆空间中的字符串对象,但引用s是指向堆区的对象的
		s.intern();//s对象去常量池中寻找后发现"1"已经存在于常量池中了
		String s2 = "1";//引用s2直接指向常量池中的“1”对象
		System.out.println(s.intern() == s2);//true。二者都指向常量池中的对象
		System.out.println(s == s2);//false。s指向堆区,s2指向常量池(对不同的jdk版本来说这都是两个位置)
		 
		//注意:下面这句只在常量池中生成了"1",并没有在常量池中生成"11"
		String s3 = new String("1") + new String("1");
		//对于jdk1.7以下,s3.intern()的做法是直接在常量池中生成一个 "11" 对象;
		//对于jdk1.7及以上,s3.intern()直接在常量池中存储指向堆区的s3(这是个对象引用),
		// 注意在此之前常量池中没有“11”,如果有的话s3.intern()就会直接指向"11"在常量池中的位置,这一点不同jdk是一样的。
		System.out.println(s3==s3.intern());//true
		//去常量池中创建对象,但是已经被s3.intern()创建过了,
		// 所以其值等于s3.intern()创建的值,即s3的值
		String s4 = "11";
		//如果没有上面的s3.intern()语句的话下面的结果就会是false,
		//即与s3.intern()相比,String s4 = "11"这句代码不会考虑堆区已存在的s3对象
		System.out.println(s3 == s4);//true

以下参考Eric新之助的文章
StringBuilder的情形和String不太一样,StringBuilder并不对常量池进行操作。

        String str1=new StringBuilder("计算机").append("软件").toString();
        //对jdk1.7及以上,下一条语句为true,即str1.intern()直接在常量池中存储了str1。
        //如果按照String的情况,如果上面一条语句在常量池分配了"计算机软件",
        //那么str1.intern()应指向常量池中的位置,下一条语句应该为false。
        System.out.println(str1.intern()==str1);
        String str2=new StringBuilder("ja").append("va").toString();
        //为false,"java"这个字符串在执行StringBuilder.toString()之前已经出现过,
        //字符串常量池中早已有它的引用。涉及JVM的初始化操作。
        System.out.println(str2.intern()==str2);
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值