有趣的Interned String讲解

请先查看一下代码,不妨猜测一下,结果会如何。

/**
 * @ClassName:     StringInternDemo.java
 * @Description:   TODO
 * @author:        mazhuo
 * @version:       V1.0  
 * @Date:          2019年11月6日 下午1:23:09 
 */
public class StringInternDemo {

	/** 
	 * @Title: main 
	 * @Description: TODO
	 * @param @param args    设定文件 
	 * @return void    返回类型 
	 * @throws 
	 */
	public static void main(String[] args) {
		String s = new String("11");
		s.intern();
		String s2 = "11";
		System.out.println(s == s2);
		
		String s3 = new String("3") + new String("4");
		s3.intern();
		String s4 = "3" + "4";
		System.out.println(s3 == s4);
		
		
	}

}

当程序执行在jdk1.6的时候:结果为false,false;当程序执行在jdk1.7和我jdk1.8的时候:结果为false和,true。要想搞清楚这个问题,首先我们需要清除一下几个问题:

1、在jdk1.6之前的版本中:字符串常量池是放在堆中的Perm区的。                                                                                                       在jdk1.7之后的版本中:字符串常量池已挪进堆中的正常区域了。

2、String s = new String("1")在系统中究竟创建了多少对象

      首先有一点可以确认,一定在java堆中创建了String的对象。如果在常量池中不存在1,那么也会在常量池中新建一个字符串1,如果已经存在就不需要创建了。

3、intern()方法是检查在常量池中是否存才该字符串,如果不存在,则将当前字符串放入常量池中;如果存在则不需要做任何操作。

     在jdk1.6之前,由于堆空间和常量池是分开的,所以放入的意思是将字符串的值复制一份放进常量池中。

     在jdk1.7之后,由于堆空间和常量池在一起,所以放入的意思是将字符串的引用地址放进常量池中。

4、= 比较的是两个字符串指向的是否是同一个对象。

那么,现在上述问题就已经很好理解了(以下仅仅解释下1.7的结果,1.6的结果已经显而易见了)

在这段代码中,首先在堆中创建了string对象,然后在常量池中创建了“11”字符串。所以s2直接指向的是常量池中的“11”,而s指向的是堆空间的对象。因而第一个结果为false。

在这段代码中,第一行的代码在堆中创建了string对象以及在常量池中的“3”和“4”。第二行intern函数检查常量池中是否有“34”,没有就将s3的引用地址放入到常量池中,这样s4就直接指向常量池中的“34”也就是s3的引用地址,这样,s3和s4指向的就是同一个地址了,所以最终的结果为true。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值