杂谈——字符串创建和存储的机制是什么

在Java语言中,字符串起着非常重要的作用,字符串的声明与初始化主要有如下两种情况:

1.String s1=“abc”

对于String s1=“abc”与String s2=“abc”语句,在JVM中存在这一个字符串常量池(其中保存着很多String对象,并且可以被共享使用,s1和s2引用的是同一个常量池中的对象。

注:运行时常量池(包含字符串常量池),在jdk1.7之前存放在方法区中,在jdk1.7字符串常量池从运行时常量池中分离出来,放在了堆里。jdk1.8中由于取消了永久代,因此方法区的的实现方式有变动,大家可以自行了解。

由于String的实现采用了Flyweight的设计模式,在创建一个字符串常量的时候,例如String s=“abc”,会首先在字符串常量池中查找是否已经有相同的字符串被定义,其判断依据是String equals(Object obj)方法的返回值。若已经定义了,则直接获取对其的引用,此时不再创建新的对象;如果没有定义的话,则首先创建这个对象,然后把它加入到字符串池中,再将它的引用返回。由于String是不可变类,一旦创建好了就不能够被修改,因此String对象可以被共享而且不会导致程序的混乱。

2.String s1=new String(“abc”)

对于String s1=new String(“abc”)语句与String s2=new String(“abc”),存在两个引用对象s1、s2,两个内容相同的字符串“abc”,它们在内存中的地址是不同的,即只要用到new总会生成新的对象。不过,字面量“abc”依旧会存在字符串常量池里面。

具体而言:

String s=“abc”;              //把“abc”放到字符串常量池中,该过程在编译时产生

String s=“ab”+“c”;         //把“ab”+“c”转换为字符串常量“abc”放到字符串常量池。

String s=new String(“abc”);    //在运行时把“abc”放到堆里。

例如:

String s1=“abc”;           //在字符串常量池中存放了一个“abc”字符串对象

String s2=“abc”;           //s2引用字符串常量池中的对象,因此不会产生新对象

String s3=new String (“abc”);    //在队中创建新的对象

String s4=new String (“abc”);    //在队中又创建了一个新的对象

为了便于理解,可以将String  s=new String(“abc”)的语句的执行人为地分解成两个过程。

第一个过程是新建对象的过程,即new String (“abc”);第二个过程是赋值的过程,即String s=。

由于第二个过程只是定义了一个名为s的String类型的变量,将一个String类型对象的引用赋值给s,因此在这个过程中不会创建新的对象。

第一个过程中new String(“abc”)会调用String类的构造函数:

public String(String original){

//body

}

在调用这个构造函数的时候,传入了一个字符串常量,因此语句new String(“abc”)也就等价于“abc”和new String()两个操作了。若在字符串常量池中不存在“abc”,则会创建一个字符串常量“abc”,并将其添加到字符串常量池中(可以认为在常量池中创建一个“abc”对象);若存在,则不创建,然后new String()会在队中创建一个新的对象,所以s3,s4指向的是队中不同的String对象,因此s3和s4的地址自然也就不相同了。

如图:

好的,既然学了知识,那么接下来就来回答一个问题:对于String类型的变量s,赋值语句s=null与s=“”是否相同?

思考一下......

怎么样,有答案了咩?

让我来揭晓答案吧——

对于赋值语句s=null,其中s是一个字符串类型的引用,它不指向任何一个字符串。而赋值语句s=“”中的s虽然也是一个字符串类型的引用,但是它指向另外一个字符串(这个字符串的值为“”,即空字符串),因此这两者是不同的。

这题是不是很简单呀?那我们再来试试下一个问题:

new String(“abc”)创建了几个对象?

创建了几个呢?

答案揭晓:一个或者两个。如果字符串常量池中原来有“abc”,那么只创建一个对象;如果字符串常量池中没有字符串“abc”,那么就会创建两个对象。

好啦,以上就是关于字符串的创建和存储机制的知识总结啦~如果大家有什么疑问,或者发现文中有什么描述不对的地方,欢迎大家留言评论,我们一起学习呀~~

Biu~~~~~~~~~~~~~~~~~~~~宫å´éªé¾ç«è¡¨æå|é¾ç«gifå¾è¡¨æåä¸è½½å¾ç~~~~~~~~~~~~~~~~~~~~~~pia! 

猜你喜欢

转载自blog.csdn.net/Searchin_R/article/details/84639325