【JAVA】字符串的创建与存储机制

版权声明:转载请注明 https://blog.csdn.net/qq_33591903/article/details/82314432

                                       字符串的创建与存储机制

在我们的编程中,常常会使用到String,那么理解String的创建与存储机制十分重要。

 

字符串有两种创建方式,分别是

(1)String s1="abc";                           s1指向的是String常量池中的字符串

(2)String s2=new String("abc");       s2指向的是堆上的对象


两种创建方式的比较:

(1)String s1=new String("abc"),需要注意的是,这样的创建方式每次都会生成新的对象,与String s2=new String("abc"),表面上内容一样,但s1与s2地址不一样。即s1.equals(s2)返回true,s1==s2返回false。

(2)String s1="abc"与String s2="abc",他们不仅内容相同,首地址也相同。那为什么呢?原来java中存在着一个字符串常量池,里面保存着很多已经创建出来的String对象,最重要的是他们可以被共享。当需要创建一个字符串时,首先会在常量池中寻找此字符串。若存在(判断依据是equals的返回值),则直接获取它的引用。若不存在,则首先创建这个字符串对象,然后将它放入到字符串常量池中,最后再获取它的引用。所以这里的s1与s2其实引用着相同的字符串对象。


下面看一道常见的笔试题:

new String("abc"),创建了几个对象?

分情况进行讨论:

(1)先进行new字符串

  String s1=new String("abc"); 
  String s2="abc";  

两个:常量池中没有abc,因此第一句执行完毕时,先在常量池中创建abc对象,再在堆上创建abc对象,最后返回堆上的这个字符串的引用。此时new语句一共创建两个对象。注意,常量池中的abc与堆上的abc不是一个对象!

(2)后进行new字符串

  String s2="abc";    
  String s1=new String("abc"); 
  

一个:第一条语句执行,由于在常量池中不存在abc字符串,则先在常量池中创建这个字符串,然后返回这个字符串的引用。第二条语句也就是new语句执行后,发现在常量池中已经存在此字符串,则不会在常量池中创建,不过依然还是要在堆上创建abc这个对象。那么new语句,一共创建了一个对象。

扫描二维码关注公众号,回复: 3495573 查看本文章

继续探讨String的不可变性

大家都知道,我们一旦创建了某个字符串,则不能改变该字符串的值,不过你可能说,下面这段代码就改变了字符串的内容啊

  String s1="abc";
  s1="def";

确实,表面上是改变了字符串的内容,其实这是jvm搞的鬼。

s1一开始引用着常量池中新创建的abc对象,当第二条语句执行后,常量池新创建def字符串对象,并将其引用赋给s1。原先的abc并没有被改变,也没有消失,它只是静静地躺在常量池中。

可见,我们改变的只是s1的引用,而没有改变引用的对象,因为String对象是不可修改的嘛。

 

猜你喜欢

转载自blog.csdn.net/qq_33591903/article/details/82314432
今日推荐