详谈String的intern()方法

Java中String的intern()方法,其设计的初衷就是重用String对象,以节省内存消耗。但是在JDK1.6和JDK1.7中intern()方法的功能有点点不同,具体怎么个不同法,且看看下面代码,这个例子是网上流传较广的一个例子:

String s1 = new String("1");  
s1.intern();  
String s2 = "1";  
System.out.println(s1 == s2);  
		  
String s3 = new String("1") + new String("1");  
s3.intern();  
String s4 = "11";  
System.out.println(s3 == s4);

输出结果为:

JDK1.6:false false  
JDK1.7:false true 

为什么会是这种结果呢?接下来我们分别对JDK1.6和JDK1.7中的intern()方法进行分析:

1、JDK1.6代码分析

首先,new String("1")会在堆中新建一个内容为"1"的对象实例,同时会把该对象实例copy一份放到常量池中。s1的引用指向的是堆中新建的对象,s1.intern()方法会在常量池中查找是否已经存在s1所引用的对象,如果存在,则会返回一个引用指向常量池中的那个对象,否则会copy一份s1所引用对象的实例放到常量池中,并返回一个引用指向常量池中的那个对象实例。s2="1"这条语句执行的时候,由于"1"已经在常量池中存在了,所以s2的引用指向的是常量池中的对象实例,也就是说s1和s2的是两个不同的引用,所以第一个打印语句为false

然后,new String("1")+new String("1")会在堆中新建两个内容为"1"的对象实例和一份内容为"11"的对象实例,同时会copy一份内容为"1"的对象实例放到常量池中。s3的引用指向的是堆中新建内容为"11"的对象实例,s3.intern()方法会在常量池中查找是否已经存在s3所引用的对象,由于常量池中没有"11"这个对象,因此会copy一份内容为"11"的对象放到常量池中,并返回一个引用指向常量池中的"11"对象实例。s4="11"这条语句执行的时候,由于"11"已经在常量池中存在了,所以s4的引用指向的是常量池中"11"的对象实例,因此s3和s4的是两个不同的引用,所以第二个打印语句也为false

2、JDK1.7代码分析

同样的,new String("1")会在堆中新建一个内容为"1"的对象实例,同时会把该对象实例copy一份放到常量池中。s1的引用指向的是堆中新建的对象,但是intern()会有所不同,s1.intern()语句执行的时候,会在常量池中查找是否已经存在s1所引用的对象,如果存在,则会返回一个引用指向常量池中的那个对象,如果不存在,则会在常量池中记录一个引用指向s1所引用的对象实例,并返回该引用。s2="1"这条语句执行的时候,由于"1"已经在常量池中存在了,所以s2的引用指向的是常量池中的对象实例,同样的,s1和s2的是两个不同的引用,所以第一个打印语句为false

然后,new String("1")+new String("1")会在堆中新建两个内容为"1"的对象实例和一份内容为"11"的对象实例,同时会copy一份内容为"1"的对象实例放到常量池中(注意:"11"的对象实例不会存入常量池)。s3的引用指向的是堆中新建内容为"11"的对象实例,s3.intern()语句执行的时候,会在常量池中查找是否已经存在s3所引用的对象,由于常量池中没有"11"这个对象,因此会在常量池中记录一个引用指向s3所引用的对象实例,并返回该引用。s4="11"这条语句执行的时候,由于常量池中已经存在了一个"11"对象实例的引用(s3指向的引用),所以常量池会把这个"11"对象实例的引用赋给s4,也就是说,s4的引用指向的是s3所指向的对象实例,因此s3和s4的是相同的引用,所以第二个打印语句为true

3、总结

总而言之,导致上述程序在JDK1.6和JDK1.7中有不同结果的原因,归根结底是String的intern()方法在JDK1.6和JDK1.7有不同的功能。在JDK1.6中,intern()方法在首次遇到字符串的时候会copy一份存到常量池,返回的引用也是常量池中对象的引用。而JDK1.7中,intern()方法在首次遇到字符串常量的时候只会在常量池中记录一个该常量的引用,该引用指向的是原有字符串的引用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值