String驻留池

来源:互联网 发布:js图片滑动切换效果 编辑:程序博客网 时间:2024/04/28 23:01

在java面试题中会经常碰到类似与这样的题目:
String str=new String("abc");
这句代码创建了几个对象?想要搞明白这个问题,不得不解释一个概念,也就是字符串常量池,也称为驻留池。对于以下代码:
Sring  s1="abc";
String s2="abc";
总共创建了几个对象?答案是一个,这两个字符串,我们在使用的时候,它们在内容上没有任何区别,更没有理由使用两份对象,所以JVM对字符串对象的创建作了一个优化,即使用了驻留池技术,当String s1="abc";时,JVM首先会在驻留池寻找,是否存在“abc”这样的一个值,当然刚开始显然是不存在的,所以JVM会在驻留池创建一个对象保存这个字符串,当再次出现String s2="abc";时,这是JVM会在驻留池寻找是否存在“abc”这样的一个值,当然,这个时候已经存在了,所以JVM会把保存该字符串对象的引用直接返回给s2,这样就避免了重复创建对象,减少了内存的开销。

那么对于这句代码:Sting str=new String("abc");

不妨这样写String s="abc";

    String str=new String(s);

先定义一个字符串常量,然后用这个字符串常量作为字符串构造方法的参数再new出一个字符串出来。在定义字符串常量“abc”时,JVM会在驻留池里创建出一个对象来保存“abc”(注意这个对象不是被new出来的,所以不会被放在堆中)当再用s作为构造参数new出一个对象时,会被放在堆内存中,所以一共创建了两个对象。

字符串有一个方法 intern(),它返回的是String类型,那这个方法是干什么的呢?

    我们平时将两个字符串作比较,一般都是用equal(),而不会用==,因为equal比较的是内容,==比较的是地址,例如以下代码:

String s1="abc";

String s2=new String("abc");

    如果用equal比较返回的是true,如果用==比较返回的则是false。

    但是利用equal方法来比较,中途经过一系列的内容比较操作,效率肯定没有==直接比较内存地址高。所以如果能想一种办法可以让两个字符串直接用==作比较并且能达到我们想用的效果,就需要用到intern()这个方法。

当一个字符串对象s2调用了intern()方法时,JVM就会在驻留池里找是否有一个对象保存的值与s2的值相同,如果相同,则直接把驻留池这个对象的引用返回回来。如果调用s2=s2.intern();因为之前s1="abc",早已在驻留池中保留了下来,并创建了一个对象,所以这个时候会直接把s1的引用返回并赋值给s2,所以,s1,s2就值向了同一块内存地址,如下代码:

String s1="abc";

String s2=new String("abc");

s2=s2.intern();//加入驻留池

System.out.println(s1==s2);

这个时候再用==比较的话,就返回的是true了,

0 0
原创粉丝点击