字符串创建与存储的机制
1)对于String s1=new String(“abc”)语句与String s2=new String(“abc”)语句,
存在两个引用对象s1、s2,两个内容相同的字符串对象”abc”,它们在内存中的地址是不同的。只要用到new总会生成新的对象。
2)对于String s1=”abc”语句与String s2=”abc”语句,在 JVM中 存在着一个字符串池,其中保存着很多String对象,并且可以被共享使用,s1、s2引用的是同一个常量池中的对象。
当创建一个字符串常量的时候,例如String s =”abc”,会首先在字符串常量池中查找是否已经有相同的字符串被定义,它的判断依据是String类equals(Object obj)方法的返回值。
如果已经定义,那么直接获取对其的引用,此时不需要创建新的对象,如果没有定义,那么首先创建这个对象,然后把它加入字符串池中,再将它的引用返回。由于String是不可变类,一旦创建好了就不能被修改,因此String对象可以被共享而且不会导致程序的混乱。
具体而言:
再例如:
此语句new String(“abc”)也就等价于”abc”和new String()两个操作。
如果在字符串池中不存在”abc”,那么会创建一个字符串常量”abc”,并将其添加到字符串池中,
如果存在,那么不创建,然后new String()会在堆中创建一个新的对象。
所以str3与str4指向的是堆中不同的String对象,地址自然也不相同了。
图1-6 两种字符串存储方式
1)直接使用双引号声明的String对象都会直接存储在常量池中。
2)new String(“abc”)创建了几个对象?
答案:一个或两个。如果常量池中原来有“abc”,那么只创建一个对象,如果常量池中原来没有“abc”,那么就会创建两个对象。